By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,190 Members | 783 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,190 IT Pros & Developers. It's quick & easy.

Displaying pictures

P: n/a
Hello

I am working on an applicaion that shows several pictures on a webpage.
These pictures are saved in a MySQL DB as BLOB. I noticed, that the web
server suffers in its performance by printing the pictures. Let's say
there are 20 pictures to show, there also are 20 queries to do. This is
the way I am doing it up to now:

index.php
<?php
foreach ($icons as $value) {
echo '<img src="./show_icon.php?icon_id=' . $value . '">';
}
?>

show_icon.php
<?php
$query = "SELECT icon FROM pictures WHERE id='$_GET['icon_id'] ";
$result = @mysql_query ($query) or die (mysql_error());
$icon = @mysql_result ($result, 0, "icon");

header("Content-type: image/png");
echo $icon;
?>

Actually this works quite well, but the performance is an issue. Is
there a more simple or more elegant way than the code above? Is there
actually a solution to do it with one query instead of 20 queries?

Thanks for your help
Stefan

Jan 14 '06 #1
Share this Question
Share on Google+
13 Replies


P: n/a
gooze wrote:
Actually this works quite well, but the performance is an issue. Is
there a more simple or more elegant way than the code above? Is there
actually a solution to do it with one query instead of 20 queries?


The improvement to gain here, is not to store the binary data in the
database, but only the reference to an image file on the server.
JW
Jan 14 '06 #2

P: n/a
Thank you for your answer. Actually I store the pictures in the DB
because they belong to the records fields. In this case it would be
meaningless to store the pictures on the filesystem, since there are
thousands of them and they are very small.

Just wondering if there is a way with only one query.

Jan 14 '06 #3

P: n/a
gooze wrote:
Thank you for your answer. Actually I store the pictures in the DB
because they belong to the records fields. In this case it would be
meaningless to store the pictures on the filesystem, since there are
thousands of them and they are very small.

Just wondering if there is a way with only one query.


Well, you could use something like:

SELECT icon FROM pictures WHERE id=$id and id=$id2 and $id=$id3...

Constructing the query from an array with ids would go as follows:

$ids = array(1,2,3,4,5,6);
$query = 'SELECT icon FROM pictures WHERE id=' . implode(' AND id=', $ids);

PS: Don't forget to escape user input which gets parsed into a query, e.g.
with the following function:

http://www.php.net/manual/en/functio...ape-string.php
JW
Jan 15 '06 #4

P: n/a
Actually the problem is not the selection from the DB, the real problem
is, how do I display the pictures in the browser after I have them in
the array? There are binary data in the queries result, and I have to
feed the browser with it...

Jan 15 '06 #5

P: n/a
gooze wrote:
Hello

I am working on an applicaion that shows several pictures on a webpage.
These pictures are saved in a MySQL DB as BLOB. I noticed, that the web
server suffers in its performance by printing the pictures. Let's say
there are 20 pictures to show, there also are 20 queries to do. This is
the way I am doing it up to now:

index.php
<?php
foreach ($icons as $value) {
echo '<img src="./show_icon.php?icon_id=' . $value . '">';
}
?>

show_icon.php
<?php
$query = "SELECT icon FROM pictures WHERE id='$_GET['icon_id'] ";
$result = @mysql_query ($query) or die (mysql_error());
$icon = @mysql_result ($result, 0, "icon");

header("Content-type: image/png");
echo $icon;
?>

Actually this works quite well, but the performance is an issue. Is
there a more simple or more elegant way than the code above? Is there
actually a solution to do it with one query instead of 20 queries?

Thanks for your help
Stefan


The performance issue you're experiencing is unlikely to be caused by
the overhead of storing images in the database. The bottleneck is
usually the Internet. Even a slow server can retrieve data from the
database faster than can be transferred across the network.

There are a couple things that could slow things down. First, make sure
the images are cached on the client-side by sending the appropriate
HTTP headers. Second, check to see if session-auto-start is turn on. If
it is, then call session_write_close() before sending the image data.

Jan 15 '06 #6

P: n/a
gooze wrote:
Actually the problem is not the selection from the DB, the real
problem is, how do I display the pictures in the browser after I have
them in the array? There are binary data in the queries result, and I
have to feed the browser with it...


You could try to use someting based on the following:

<?php

session_start();

if (isset($_SESSION['img']) && isset($_GET['show'])) {
header("Content-Type: image/jpeg");
print base64_decode($_SESSION['img']);
exit;
}

// Prepare some test data
$binary = file_get_contents('103.jpg');
$array = array_fill(0, 3, $binary);

foreach ($array as $e) {
$_SESSION['img'] = base64_encode($e);
// Timestamp appended to prevent caching
echo '<img src="', $_SERVER['PHP_SELF'], '?', time(), '&show=1" />';
}

?>
JW
Jan 15 '06 #7

P: n/a
This might work a little better:

<?php

session_start();

if (isset($_SESSION['img']) && isset($_GET['id'])) {
if (isset($_SESSION['img'][$_GET['id']])) {
header("Content-Type: image/jpeg");
print base64_decode($_SESSION['img'][$_GET['id']]);
exit;
}
}

// Prepare some test data
$binary = file_get_contents('103.jpg');
$binary2 = file_get_contents('283.jpg');
$array = array($binary, $binary2);

$_SESSION['img'] = array();
foreach ($array as $e) {
$_SESSION['img'][] = base64_encode($e);
}

for ($i = 0, $m = count($_SESSION['img']); $i < $m; $i++) {
print "<img width=100 src='{$_SERVER['PHP_SELF']}?id=$i' />";
}

?>

But also read Chung's advice...
JW
Jan 15 '06 #8

P: n/a
actually, you don't need to do a base64_decode() on a blob if it wasn't
encoded that way. if it's real binary data, all you need is stripslashes().
that's faster.

"Janwillem Borleffs" <jw@jwscripts.com> wrote in message
news:43***********************@news.euronet.nl...
This might work a little better:

<?php

session_start();

if (isset($_SESSION['img']) && isset($_GET['id'])) {
if (isset($_SESSION['img'][$_GET['id']])) {
header("Content-Type: image/jpeg");
print base64_decode($_SESSION['img'][$_GET['id']]);
exit;
}
}

// Prepare some test data
$binary = file_get_contents('103.jpg');
$binary2 = file_get_contents('283.jpg');
$array = array($binary, $binary2);

$_SESSION['img'] = array();
foreach ($array as $e) {
$_SESSION['img'][] = base64_encode($e);
}

for ($i = 0, $m = count($_SESSION['img']); $i < $m; $i++) {
print "<img width=100 src='{$_SERVER['PHP_SELF']}?id=$i' />";
}

?>

But also read Chung's advice...
JW

Jan 15 '06 #9

P: n/a
where do I go to find out how to manipulate the cache with headers?

"Chung Leong" <ch***********@hotmail.com> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
gooze wrote:
Hello

I am working on an applicaion that shows several pictures on a webpage.
These pictures are saved in a MySQL DB as BLOB. I noticed, that the web
server suffers in its performance by printing the pictures. Let's say
there are 20 pictures to show, there also are 20 queries to do. This is
the way I am doing it up to now:

index.php
<?php
foreach ($icons as $value) {
echo '<img src="./show_icon.php?icon_id=' . $value . '">';
}
?>

show_icon.php
<?php
$query = "SELECT icon FROM pictures WHERE id='$_GET['icon_id'] ";
$result = @mysql_query ($query) or die (mysql_error());
$icon = @mysql_result ($result, 0, "icon");

header("Content-type: image/png");
echo $icon;
?>

Actually this works quite well, but the performance is an issue. Is
there a more simple or more elegant way than the code above? Is there
actually a solution to do it with one query instead of 20 queries?

Thanks for your help
Stefan


The performance issue you're experiencing is unlikely to be caused by
the overhead of storing images in the database. The bottleneck is
usually the Internet. Even a slow server can retrieve data from the
database faster than can be transferred across the network.

There are a couple things that could slow things down. First, make sure
the images are cached on the client-side by sending the appropriate
HTTP headers. Second, check to see if session-auto-start is turn on. If
it is, then call session_write_close() before sending the image data.

Jan 15 '06 #10

P: n/a
Jim Michaels wrote:
actually, you don't need to do a base64_decode() on a blob if it
wasn't encoded that way. if it's real binary data, all you need is
stripslashes(). that's faster.


When you look closely to my example, you will notice that the binary data is
base64 encoded before it's stored in the session.
JW
Jan 15 '06 #11

P: n/a
Jim Michaels wrote:

Don't top-post
where do I go to find out how to manipulate the cache with headers?


http://www.google.nl/search?q=cache+headers
JW
Jan 15 '06 #12

P: n/a
d
"gooze" <g0****@gmx.net> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
Thank you for your answer. Actually I store the pictures in the DB
because they belong to the records fields. In this case it would be
meaningless to store the pictures on the filesystem, since there are
thousands of them and they are very small.

Just wondering if there is a way with only one query.


Just keep the filenames with the records to which they belong. As to
storing thousands of small files, that's exactly what a filesystem is for
and exactly what a database is not for :)
Jan 17 '06 #13

P: n/a
d
"Chung Leong" <ch***********@hotmail.com> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
gooze wrote:
Hello

I am working on an applicaion that shows several pictures on a webpage.
These pictures are saved in a MySQL DB as BLOB. I noticed, that the web
server suffers in its performance by printing the pictures. Let's say
there are 20 pictures to show, there also are 20 queries to do. This is
the way I am doing it up to now:

index.php
<?php
foreach ($icons as $value) {
echo '<img src="./show_icon.php?icon_id=' . $value . '">';
}
?>

show_icon.php
<?php
$query = "SELECT icon FROM pictures WHERE id='$_GET['icon_id'] ";
$result = @mysql_query ($query) or die (mysql_error());
$icon = @mysql_result ($result, 0, "icon");

header("Content-type: image/png");
echo $icon;
?>

Actually this works quite well, but the performance is an issue. Is
there a more simple or more elegant way than the code above? Is there
actually a solution to do it with one query instead of 20 queries?

Thanks for your help
Stefan


The performance issue you're experiencing is unlikely to be caused by
the overhead of storing images in the database. The bottleneck is
usually the Internet. Even a slow server can retrieve data from the
database faster than can be transferred across the network.

There are a couple things that could slow things down. First, make sure
the images are cached on the client-side by sending the appropriate
HTTP headers. Second, check to see if session-auto-start is turn on. If
it is, then call session_write_close() before sending the image data.


Remember that reading images from a database requires the whole image to be
passed around from DB server to php, then php out to the web server, to the
client. That is a significant hit on a site with only a reasonable amount
of traffic.

That session_write_close() tip is a good one, though - more than two scripts
using the same session will cause the third to time out, which is quite
unexpected to most people :)
Jan 17 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.