0

I am building an in-house app for Client Relationship Management.

This app is fairly straight forward. It collects client information and stores it for later use.

One part of the information collected is an image of the clients photo identification. I am storing this image in its own table in mySQL database.

I have been looking for a way to display the image in a small preview window along side the clients information (name, address, etc). What I am finding for possible solutions are very old and depreciated at this point, or refer to displaying an image where just the URL of the file is stored in the database and the image itself is saved in a folder on the server.

The code I currently have does not display anything in the HTML but blank space. I did have one version before this that displayed the raw data from the BLOB, but it was crashing everything so I did not keep it to show you here.

My question is, is there a resource someone can point me to that is specifically about how this type of information is used by a web browser and how to organize it appropriatly for display? OR, if this is all wrong for some reason, can someone point me towards documentation that is a better way to do this? I am not experienced with any of this, and have trouble searching for answers sometimes due to lack of correct terminology.

The table looks like:

TABLE NAME = "photoid" row 1 = "id" (auto increment) row 2 = "name" (varchar) row 3 = "mime" (varchar) row 4 = "size" (bigint) row 5 = "data" (medium blob) row 6 = "created" (datetime) row 7 = "client_id" (varchar) 

The HTML:

<img width="400" height="200" src="<?php include ('client_display_photoid.php');?>" /> 

The PHP:

<?php include ('connect.php');?> <?php $client_id = htmlspecialchars($_POST['client_id']); // prepare stmt, bind param, execute $stmt = $conn->prepare("SELECT mime, name, size, data FROM photoid WHERE client_id = ?"); $stmt->bind_param("s", $client_id); $stmt->execute(); // bind results $stmt->bind_result($mime, $name, $size, $data); // Print headers header("Content-Type: $mime"); header("Content-Length: $size"); header("Content-Disposition: attachment; filename = $name"); // Print data echo $data; ?> <?php include ('disconnect.php');?> 

EDIT 1: After reviewing the comments, I was able to get rid of the "blank space" that was displaying by removing the open PHP tags. I also looked at the link provided and changed my code as follows.

HTML:

<img width="300px" height="150px" src="data:image/jpeg;base64,<?php echo base64_encode( $data ); ?>" /> 

PHP:

<?php include ('connect.php'); $stmt = $conn->prepare("SELECT data FROM photoid WHERE client_id = ?"); $stmt->bind_param("s", $client_id); $stmt->execute(); $stmt->bind_result($data); include ('disconnect.php'); ?> 

The following is what is now displayed when I try to display the image:

<img width="300px" height="150px" src="data:image/jpeg;base64," /> 

EDIT 2:

I have tried the following code... HTML:

<img src='client_display_photoid.php?client_id=182' /> 

PHP:

<?php include ('connect.php'); $sql='select `mime`,`data` from `photoid` where `client_id` = ?'; $stmt=$conn->prepare( $sql ); if( $stmt ){ $stmt->bind_param('s', $client_id ); $result=$stmt->execute(); $stmt->store_result(); if( $result && $stmt->num_rows==1 ){ $stmt->bind_result( $mime, $data ); $stmt->fetch(); $stmt->close(); $data=base64_decode( $data ); #$mime=image_type_to_mime_type( $mime ); $oImg = imagecreatefromstring( $data ); switch( $mime ){ case IMAGETYPE_JPEG: header( 'Content-Type: image/jpeg' ); imagejpeg( $oImg ); break; case IMAGETYPE_PNG: header( 'Content-Type: image/png' ); imagepng( $oImg ); break; case IMAGETYPE_GIF: header( 'Content-Type: image/gif' ); imagegif( $oImg ); break; } imagedestroy( $oImg ); } } include ('disconnect.php'); ?> 

All I get back in the browser is:

<img src='client_display_photoid.php?client_id=182' /> 
12
  • I think this should help you: stackoverflow.com/q/7793009/2191572 Commented Jan 18, 2018 at 15:31
  • I would suggest that <img width="400" height="200" src="<?php include ('client_display_photoid.php');?>" /> is incorrect and unlikely to produce what you are hoping for ~ though without seeing it's content it is hard to know. The storing of blobs in the db does mean the db will potentially grow to a disproportionately large size compared to the number of records ~ why is it a bad thing to just store the path to the image? Commented Jan 18, 2018 at 15:32
  • "refer to displaying an image where just the URL of the file is stored in the database and the image itself is saved in a folder on the server" is usually the preferred method, much easier to manipulate, doesn't require a database for resource grabs, readable/manageable code. And as @RamRaider said, less db bloat from all the blobs. Commented Jan 18, 2018 at 15:33
  • Specifically, stackoverflow.com/a/7795225/2191572 would help you achieve what you need with minimal change to your code Commented Jan 18, 2018 at 15:35
  • Possible duplicate of How to retrieve images from MySQL database and display in an html tag Commented Jan 18, 2018 at 15:35

2 Answers 2

0

The following ought to help get this sorted for you - the db stores the base64 encoded data as a blob and creates the image on the fly using php and imagecreatefromstring. The below code worked for me in test so with care you should be able to modify this to work in your environment. One difference is the use of an integer mimetype in the db rather than a string.

The above $mime is an integer but using image_type_to_mime_type on that returned value would yield the mime type string.. It just means you have to modify that bit to work with strings rather than ints.

mysql> describe photoid; +-----------+---------------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+---------------------+------+-----+---------------------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(50) | NO | | NULL | | | mime | tinyint(3) unsigned | NO | | NULL | | | size | int(11) | NO | | NULL | | | data | mediumblob | YES | | NULL | | | created | datetime | NO | | 0000-00-00 00:00:00 | | | client_id | varchar(50) | NO | MUL | NULL | | +-----------+---------------------+------+-----+---------------------+----------------+ 

enter image description here


<?php /* display profile picture: photoid.php */ $client_id=!empty( $_GET['client_id'] ) ? filter_input( INPUT_GET, 'client_id', FILTER_SANITIZE_STRING ) : false; if( $client_id ){ $dbhost = 'localhost'; $dbuser = 'root'; $dbpwd = 'xxx'; $dbname = 'xxx'; $db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname ); $sql='select `mime`,`data` from `photoid` where `client_id` = ?'; $stmt=$db->prepare( $sql ); if( $stmt ){ $stmt->bind_param('s', $client_id ); $result=$stmt->execute(); $stmt->store_result(); if( $result && $stmt->num_rows==1 ){ $stmt->bind_result( $mime, $data ); $stmt->fetch(); $stmt->close(); $data=base64_decode( $data ); #$mime=image_type_to_mime_type( $mime ); $oImg = imagecreatefromstring( $data ); switch( $mime ){ case IMAGETYPE_JPEG: header( 'Content-Type: image/jpeg' ); imagejpeg( $oImg ); break; case IMAGETYPE_PNG: header( 'Content-Type: image/png' ); imagepng( $oImg ); break; case IMAGETYPE_GIF: header( 'Content-Type: image/gif' ); imagegif( $oImg ); break; } imagedestroy( $oImg ); } } } ?> 

Within the html you can call this like this:

<img src='photoid.php?client_id=5a60cc8780ee6' /> 

ie:

<?php #include __DIR__ . '/db.php'; ?> <!doctype html> <html> <head> <meta charset='utf-8' /> <title>Display the PHP generated image</title> </head> <body> <!-- The main content on the page will be, I guess, generated using PHP so a db lookup to get the records and render appropriate content $res=$db->query('select * from blah'); while( $rs=$res->fetch_object() ){ echo "content <img src='photoid.php?client_id={$rs->id}' />"; } --> <img src='photoid.php?client_id=5a60e11e02d18' /> </body> </html> 
Sign up to request clarification or add additional context in comments.

3 Comments

When I try this code in my app I just get <img src='photoid.php?client_id=5a60cc8780ee6' />
erm.. the client_id in the example/demo I gave is specific to my db and these results. How have you used the above ?
Ive edited my original post to show what I changed when using the above code.
0

I messed around with this a bunch today and found that changing my PHP to the following allowed me to just use a simple PHP INCLUDE in the HTML to display the image as desired.

It looks like the WHILE statement was what did the trick. I also used some of the suggestions provided and took advantage of ECHO-ing HTML within the PHP code.

Much thanks to everyone who commented and helped.

PHP:

<?php if (!empty($_POST['client_id'])) { // connect to database include ('connect.php'); // prepare stmt, bind param, execute $stmt = $conn->prepare("SELECT data FROM photoid WHERE client_id = ?"); $stmt->bind_param("s", $client_id); $stmt->execute(); // bind results $stmt->bind_result($data); while ($stmt->fetch()) { } echo '<img width="300" src="data:image/jpeg;base64,'.base64_encode( $data ).'"/>'; // close statement $stmt->close(); // disconnect from databse include ('disconnect.php'); } ?> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.