Hello! I'm a newbie in php programming. I followed some online tutorial about an image gallery using blob-storage which can be found here. Everything went well until when i try to retrieve the image, it is displayed in gibberish characters.

Here's the code. I really need some help about this. Thanks!


<?php
$db_host = 'localhost'; // don't forget to change 
$db_user = 'root'; 
$db_pwd = '';

$database = 'mydb';
$table = 'gallery';
// use the same name as SQL table

$password = '123';
// simple upload restriction,
// to disallow uploading to everyone


if (!mysql_connect($db_host, $db_user, $db_pwd))
    die("Can't connect to database");

if (!mysql_select_db($database))
    die("Can't select database");

// This function makes usage of
// $_GET, $_POST, etc... variables
// completly safe in SQL queries
function sql_safe($s)
{
    if (get_magic_quotes_gpc())
        $s = stripslashes($s);

return mysql_real_escape_string($s);
}

// If user pressed submit in one of the forms
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
    // cleaning title field
    $title = trim(sql_safe($_POST['title']));

if ($title == '') // if title is not set
    $title = '(empty title)';// use (empty title) string

if ($_POST['password'] != $password)  // cheking passwors
    $msg = 'Error: wrong upload password';
else
{
    if (isset($_FILES['photo']))
    {
        @list(, , $imtype, ) = getimagesize($_FILES['photo']['tmp_name']);
        // Get image type.
        // We use @ to omit errors

        if ($imtype == 3) // cheking image type
            $ext="png";   // to use it later in HTTP headers
        elseif ($imtype == 2)
            $ext="jpeg";
        elseif ($imtype == 1)
            $ext="gif";
        else
            $msg = 'Error: unknown file format';

        if (!isset($msg)) // If there was no error
        {
            $data = file_get_contents($_FILES['photo']['tmp_name']);
            $data = mysql_real_escape_string($data);
            // Preparing data to be used in MySQL query

            mysql_query("INSERT INTO {$table}
                            SET ext='$ext', title='$title',
                                data='$data'");

            $msg = 'Success: image uploaded';
        }
    }
    elseif (isset($_GET['title']))      // isset(..title) needed
        $msg = 'Error: file not loaded';// to make sure we've using
                                        // upload form, not form
                                        // for deletion


    if (isset($_POST['del'])) // If used selected some photo to delete
    {                         // in 'uploaded images form';
        $id = intval($_POST['del']);
        mysql_query("DELETE FROM {$table} WHERE id=$id");
        $msg = 'Photo deleted';
    }
}
}
elseif (isset($_GET['show']))
{
    $id = intval($_GET['show']);

$result = mysql_query("SELECT ext, UNIX_TIMESTAMP(image_time), data
                         FROM {$table}
                        WHERE id=$id LIMIT 1");

if (mysql_num_rows($result) == 0)
    die('no image');

list($ext, $image_time, $data) = mysql_fetch_row($result);

$send_304 = false;
if (php_sapi_name() == 'apache') {
    // if our web server is apache
    // we get check HTTP
    // If-Modified-Since header
    // and do not send image
    // if there is a cached version

    $ar = apache_request_headers();
    if (isset($ar['If-Modified-Since']) && // If-Modified-Since should exists
        ($ar['If-Modified-Since'] != '') && // not empty
        (strtotime($ar['If-Modified-Since']) >= $image_time)) // and grater than
        $send_304 = true;                                     // image_time
}


if ($send_304)
{
    // Sending 304 response to browser
    // "Browser, your cached version of image is OK
    // we're not sending anything new to you"
    header('Last-Modified: '.gmdate('D, d M Y H:i:s', $ts).' GMT', true, 304);

    exit(); // bye-bye
}

// outputing Last-Modified header
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $image_time).' GMT',
        true, 200);

// Set expiration time +1 year
// We do not have any photo re-uploading
// so, browser may cache this photo for quite a long time
header('Expires: '.gmdate('D, d M Y H:i:s',  $image_time + 86400*365).' GMT',
        true, 200);

// outputing HTTP headers
header('Content-Length: '.strlen($data));
header("Content-type: image/jpeg");

// outputing image
echo $data;
exit();
}
?>
<html><head>
<title>MySQL Blob Image Gallery Example</title>
</head>
<body>
<?php
if (isset($msg)) // this is special section for
                 // outputing message
{
?>
<p style="font-weight: bold;"><?=$msg?>
<br>
<a href="<?=$PHP_SELF?>">reload page</a>
<!-- I've added reloading link, because
     refreshing POST queries is not good idea -->
</p>
<?php
}
?>

<h1>Blob image gallery</h1>
<h2>Uploaded images:</h2>
<form action="<?=$PHP_SELF?>" method="post">
<!-- This form is used for image deletion -->

<?php
$result = mysql_query("SELECT id, image_time, title FROM {$table} ORDER BY id DESC");
if (mysql_num_rows($result) == 0) // table is empty
    echo '<ul><li>No images loaded</li></ul>';
else
{
    echo '<ul>';
    while(list($id, $image_time, $title) = mysql_fetch_row($result))
    {
        // outputing list
        echo "<li><input type='radio' name='del' value='{$id}'>";
        echo "<a href=" . $PHP_SELF . "?show={$id}’>{$title}</a> &ndash; ";
        echo "<small>{$image_time}</small></li>";
    }

echo '</ul>';

echo '<label for="password">Password:</label><br>';
echo '<input type="password" name="password" id="password"><br><br>';

echo '<input type="submit" value="Delete selected">';
}
?>

</form>
<h2>Upload new image:</h2>
<form action="<?=$PHP_SELF?>" method="POST" enctype="multipart/form-data">
<label for="title">Title:</label><br>
<input type="text" name="title" id="title" size="64"><br><br>

<label for="photo">Photo:</label><br>
<input type="file" name="photo" id="photo"><br><br>

<label for="password">Password:</label><br>
<input type="password" name="password" id="password"><br><br>

<input type="submit" value="upload">
</form>

    If you are going to output an image via PHP (or any other programmatic method), you cannot output anything else -- including HTML text. You will need to have each such image accessed via a separate HTTP call to the script that will output it, then call that "image server" script as/where needed within the main script/HTML file from the src URI in the relevant <img> tags.

    Main script:

    <html><etc....>
    <?php
    // whatever processing is needed to determine the ID of the image to be displayed
    // resulting in that ID being stored in $imgId
    ?>
    <img src='http://example.com/image_server.php?id=<?php echo $imgId; ?>' />
    <etc....>
    

    image_server.php:

    <?php
    // use $_GET['id'] to get image from DB
    // if found set desired HTTP headers via header()
    // then output the retrieved image bytes
    header("Content-Type: image/jpeg");
    echo $imgDataFromDb;
    exit; // make sure nothing else gets output
    ?>
    

    However, generally speaking, using the DB to store the actual image data is inefficient and can put quite a load on your database server. The most common solution is to only store meta data about the images in the DB, including any file path/name info needed to access the actual image file stored in the web server's file system. Then your image server script would only need to access that path/name info and, for example, use it in a [man]readfile/man call to output that image.

      Write a Reply...