Show Me the Image! PHP Help

At this point, you have all your data, and you can even get the image for a particular user. All that’s left is to actually show the image, right?

Yes, but you have an entirely different situation than when you had the image on a file system and just needed to point at that file. In this case, you must load the actual raw image data from your database and then somehow let the browser know, “Hey, this is an image, not just text. Display it like an image.” That’s not particularly difficult; but it’s different from what you’ve been doing.

Displaying an Image

First, you need a script that can load and display an image. Once that’s done, it’s easy to reference that display script in show_image.phps Therefore, the script is the important piece, with all the new code.

Create a new script. and call it image. You can start out with the basic script shell that all your scripts now have:
<?php
require_once’ ../scripts/app_config.php’;
require_once’ ../scripts/database_connection.php’;
?>

MAKE A GAME PLAN FOR YOUR SCRIPT
Map out the exact steps that need to happen:
1. Get an image 10 from the request.
2. SELECT query from the images table by using that image 10.
3. Run the SELECT query and get the results.
4. Grab what should be the only row from those results.
5. Inform the browser that it’s about to receive an image.
6. Inform the browser what kind of image it’s about to receive.
7. Give the browser the image data.

With the exception of these last few steps, you’re probably already whirring away, figuring out exactly what sort of code you need to write. But, there’s a lot of error handling that has to happen along the way, too:

1. Ensure that an image 10 was sent to the script.
2. Ensure that the 10 maps to an image in the images table.
3. Deal with general problems that occur while loading or displaying the image data.

Again, though, none of this is particularly hard. Time to get to work.

GET THE IMAGE 10
First up, you need to get an ID to use for loading the image from the database. This step is also where you can do some initial error handling: if no ID comes in as part of the request, something’s gone wrong.

Simple enough, and a lot like code you’ve written before in Show_users.php Once again, handle_error makes dealing with problems, if they do occur, a piece of cake.

BUILD AND RUN A SELECT QUERY
Next. you can use your new friend, sprintf. to construct a SQL query, and an older friend, mysql_ query, to get a result set:

<?php
// require Statements
// Get the image ID
// Build the SELECT statement
$select_query = sprintf(“SELECT * FROM images WHERE image_id = %d”,
$image_id);
// Run the query
$result = mysql_query($select_query);
?>
Nothing new here, either.

GET THE RESULTS, GET THE IMAGE, AND DEAL WITH POTENTIAL ERRORS

Now, you can grab the data from $result. In the past, you’ve done that in a few way? Early on, you looped over all of the rows returned from a query:

You also used an if statement if you expected only a single result:

if ($result) { $row = mysql_fetch_array($result);
// Deal with the single result
else {
handle_error(“there was a problem finding your information in our system.”,
“Error locating user with ID {$user_id}”);

This statement assumes that as long as $result is valid, you have a row. Further, it ignores any rows other than the first one, knowing that the SQL query that generated these results can only return a single row.

In Show_user.php you want something similar to this latter approach. But it’s possible to check and ensure that you have a result without encasing everything in an if:

<?php
// require statements
// Get the image ID
// Build and run the query
// Get the result and handle errors from getting no result
if (mysql_num_rows($result) == 0) {
handle_error(“we couldn’t find the requested image.”,
“No image found with an 10 of ” • $image_id • “.”)j
$image = mysql_fetch_array($result)j
?>

‘This approach is cleaner because it keeps your code moving along once the error has been dealt with. (For more on why this sequence is more natural, read the box on page 317.)

TELL THE BROWSER WHAT’S COMING

You have the information you want from images, but you can’t just toss that to the browser. Well, you could, but the browser would become confused. It’s used to dealing with HTML; but raw binary data is something else altogether.

There are a couple of things about which you need to apprise the browser:

• What kind of content is coming? This information is passed to the browser through a MIME type. It is usually something like text.html or text.html, or in the case of images, images/jpeg  or images/gif or images/png.

• If that type is binary-as images are-what amount or size of information is coming? The browser needs to know so it can figure out when it’s done receiving, information.

You already have the tools you need to communicate with the browser.

header(” Location: ” . HTTP_WWW_Root “scripts/show _error. php?”
error_message={$user_error_message}&” .
system_error_message={$system_error_message}”);

This line communicates directly to the browser. It’s sending a header called Location to the browser. The value of that header is a location, a URL, and the browser knows ‘: that when it gets a Location header, go to the URL specified by the header’s value.

The PHP header function is the mechanism by which you can speak directly to the browser. As for the two pieces of information you need to send-the content type and the size of that content-browsers have specific headers for both:

″ Content-type Use this to alert a browser to what the MIME type is of the content you’re about to send,
″ Content-length Use this to provide the size (the “length” in bytes) of the information you’re about to send.

At this point. you have both of these pieces of information in your images table, in the mime_type column and the file_size column.

Put all.this together, and you have two lines of code to add to show_image,php:

<?php
// require statements
// Get the image 1D
// Build and run the query
// Get the result and handle errors from getting no result
// Tell the browser what’s coming with headers
header(‘Content-type: ‘ • $image[‘mime_type’]);
header(‘Content-length: ‘ • $image[‘file_size’]);
?>

That’s it The browser expects a certain type of information (in your case, image/jpeg or image/gif in most cases), it knows the size of the information and now it just needs the actual information itself,

SEND THE IMAGE DATA
All that’s left is one easy step, You need to set up an echo statement to send the image to the browser:
<?php
// require statements
// Get the image ID
// Build and run the query
// Get the result and handle errors from getting no result
// Tell the browser what’s coming with headers

echo $image[‘image_data’];
?>

That’s it. This data is not a string of text; it’s the raw binary information pulled from a BLOB column in your images table, sent out bit by bit. But the magic isn’t in this line. The magic is you telling the browser that this is a certain kind of information and a certain size. Those details let the browser know, “This is an image coming. Treat it like one.”

Handling Errors with try and catch

At this point. you’ve knocked out your list of things to do to show an image:

1. Get an image 10 from the request.
2. Build a SELECT query from the images table using that image 10.
3. Run the SELECT query and get the results.
4. Grab what should be the only row from those results.
5. Inform the browser that it’s about to receive an image.
6. Tell the browser what kind of image it’s about to receive.
7. Give the browser the image data.

All done; excellent. And, the script is short, too; clean and easy to follow. That’s a win by every account.

You’ve also taken care of most of your error handling:

1. Ensure that an image 10 was sent to the script.
2. Ensure that the 10 maps to an image in the images table.
3. Deal with general problems that occur while loading or displaying the image data.

The first two are done, but what about those so-called general problems? What happens is,for example, there’s an error sending the Content-type header? Or perhaps sending the Content -length header? And what about echoing out the image data? Doesn’t that seem like something that can go bad? What if the image data is corrupt, or something happens in pulling data from the result set, or if the browser can’t handle a particular type of image that your script tries to send?

In all of these cases, you receive an error that’s unaccounted for. And when you have these general sort of errors-errors that don’t fit into the black-and-white, can check ahead of time and make sure there’s no problem” mold-you need a way to deal with them.

The rub here is that you can’t pin these things down. You need a way to say, “While this entire chunk of code is running, if a general problem happens, do this …” The good news is that you have a “do this” in handle_error. PHP provides a way to do just this with something called a try/catch block.

The try part of a try/catch block defines a segment (a block) of your error-prone code to which you would like to pay special attention. Essentially, you’re saying, “Try this code.” The catch path of the try/catch block is run only if an error occurs. If anything goes wrong within the try block, the catch part of the block runs.

Not only that, but in the catch, an object is handed off: an Exception. This Exception has information about what went wrong, so you can report on that=say to a custom function such as handle error.

To put this into place in show_image.php first, surround all your error-prone code with a try and curly braces, like this:

Handling Errors with try and catch

Whenever anything goes wrong, the PHP interpreter will throw out an Exception object, reporting the problem, and then go to the catch block:

Handling Errors with try and catch

You can see that this line almost looks like a function: the catch code takes control, and it receives an Exception object. $exc is the variable name of the exception, so you can reference that exception if you need to.

Finally, you should do something useful in this catch block:

Handling Errors with try and catch

With this code, anytime there’s an error, handle_error comes to the rescue. As usual, you pass handle_error a friendly string as well as some extra information for the programmers who might be looking on. In this case, that message comes from exc, and the getMessage method. An object in PHP doesn’t have functions; it has methods.

When this code runs, it reports any error that might have occurred and stops PHP from trying to continue on in the try block.

Here’s what you should have for show_image.php:

Handling Errors with try and catch

All that’s left is some testing to verify that things work.

Test, Test, Always Test

First. start MySQL and find an image that’s been inserted. Make a note of that image’s ID.

Handling Errors with try and catch

Next, open your browser and type the URL for Show_image.php, but don’t press Enter; if you do, you should get the error shown in Figure 10-4 because you didn’t supply an ID.

FIGURE 10-4

FIGURE 10-4

Now, add the image ID to the URL like this show_image.php Put that in your browser’s address bar (along with the rest of your domain name and path), and you should see something similar to Figure 10-5.

FIGURE 10-5

FIGURE 10-5

Posted on January 12, 2016 in Binary Objects and Image Loading

Share the Story

Back to Top