0

I am currently creating a program which displays random images from a click event.

I have code which should (but currently isnt) display random images from a folder of mine however, I have these images uploaded in my database instead (defined as large blobs). I would like to randomly output these images from my database instead (with the use of MySqli of course).

How can I approach this?

My current code at the moment is :

JS:

    var myImg = ["fruit1.jpg", "fruit2.jpg", "fruit3.jpg", "fruit4.jpg", "fruit5.jpg", "fruit6.jpg"];



//create a function named displayImage
//it should not have any values passed into it

var inputs = document.querySelectorAll('input');

for(var i = 0; i < inputs.length; i++) {
  inputs[i].addEventListener('click', function() {
    var num = Math.floor(Math.random() * 12);
    this.nextElementSibling.src = myImg[num];
  })
}

Example of the relevant html code:

<div class="boxa">A1
    <input type=button value="Display Random Image">
    <img src="config.php" name="canvas" />
</div>
TheBiz
  • 83
  • 7
  • Take JavaScript completely out of the equation; you'll need PHP to interact with your database, and won't need JavaScript for this at all. Have your PHP connect to the database, return all of your images in an array, pick one at random, and then `echo` it into the `src` part of your `` (like `echo ""`). – Obsidian Age Jul 12 '18 at 00:38
  • @ObsidianAge if he wants to do it with a click event, and not with a reload, he can use AJAX. – Ryan Kozak Jul 12 '18 at 00:41
  • That's one option, absolutely. But you'll still need to return the desired image(s) in the response from the AJAX call, and then use JavaScript to parse the response (ultimately using `.src` to store one image from the response). – Obsidian Age Jul 12 '18 at 00:43
  • I think the ajax side of things is confusing me the most. In terms of php and MySQLi, I just have to fetch the image from the database and output it, and then encode it as base 64, is that correct? Would someone be able to give me an example of this with the Ajax code please? @RyanKozak – TheBiz Jul 12 '18 at 01:03
  • And @ObsidianAge (wouldn’t let me tag 2 people at once) – TheBiz Jul 12 '18 at 01:03
  • Using inline [base64](https://stackoverflow.com/questions/8499633/how-to-display-base64-images-in-html) is one method, another is to reference a php script as the src, and it [outputs the raw binary](https://stackoverflow.com/questions/1851849/output-an-image-in-php) with proper `header` settings. – IncredibleHat Jul 12 '18 at 01:38
  • @TheBiz If you use base64 for this, you're doing it wrong, creating significant overhead in the transport, overhead in the image loading, and spending time writing code you don't need to write. – Brad Jul 12 '18 at 02:20

3 Answers3

0

As many of us observed, you're currently using javascript to retrieve items/data from the database. There are two ways for you to get the image in your database. First is to get rid of your javascript and retrieve data using PHP, or use third-party js plugin like AJAX so you could still retrieve data using javascript. The difference is, AJAX doesn't reload the entire page. But since, you didn't tag AJAX in your question, we could do it in php.

index.php

<?php
  ... //Connection to database
  session_start();
  $_SESSION['ctr'] = ((isset($_SESSION['ctr'])) ? $_SESSION['ctr'] : 0);
  if(isset($_GET['incrementBtn']){
    $_SESSION['ctr']++;
  }
  $ctr = $_SESSION['ctr'];
  $imageArray = array();
  $result = $db->query("Select * from image"); //Retrieval Query
  for($x=0; $rows = mysqli_fetch_array($result); $x++){
    $imageArray[$x] = $rows['images']; //The Attribute name of your image, here i simply assume that it is 'image'
  }
?>
<div class="boxa">A1
    <form method="get" action="index.php">
        <input type="submit" name="incrementBtn" value="Display Random Image">
    </form>

    <img src="<?php echo $imageArray[$ctr]; ?>" name="canvas" />
</div>

Hope this helps. Please correct me if something went wrong with this code, since I haven't tried this code because im using my mobile to answer this question. Thanks! :D

Alvin Ching
  • 25
  • 1
  • 7
0

On the client side, there's no reason to make an AJAX call to figure out what image to show. Your <img> tag can reference your PHP script directly:

<img src="getRandomImage.php" />

Normally, you're using PHP to return HTML, but there's no reason it can't return binary data as well. Here, we're just letting the browser do the work of making the request. Now, it's up to your server-side script to output the image.

In getRandomImage.php, first you'll need to query for a random image. Best to let the database engine do this, as there's no sense in shuffling excess data between your application and your database server. Your query will look something like this:

SELECT blobData FROM images ORDER BY RAND() LIMIT 1;

(blobData in this case is the name of the column containing the binary image data.)

Use your usual methods for making the query and getting the data. Now, to output it to something the browser can use, first we have to set the appropriate headers. The first sets the response content type to be JPEG. (Change it to whatever is appropriate for you image type, if you're not outputting JPEG.

header('Content-Type: image/jpeg');

Next, we need to prevent caching. This is important, as we're changing the response data for every request to this script:

header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

Now, just output your image data.

echo $row['blobData'];

If all goes well, you should see the image in your image tag.

Improvements

Normally when you make a GET request, all subsequent GET requests to the same URL with the same request data should return the same response. While this isn't a technical requirement, it's a best practice that enables caches and what not to work correctly.

It is possible for you to still have cacheable images, while making the selection random. To do this, all you have to do is redirect to the image. For example, getRandomImage.php might do something like this:

SELECT id FROM images ORDER BY RAND() LIMIT 1;

Then the response might just be a redirect:

header('Location: image.php?id=' . $row['id']);

Then in image.php, you'll load the image by ID (not randomly) and output it, just as we did in the first example. Ideally, your images would just be static files and be accessible without this subsequent database lookup, and that random selection script could redirect to a static file directly. By default, PHP will do a 302 status code causing a non-permanent redirect which won't be cached in well-behaved clients.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • Thank you for your answer! I will try it once I’m at the my computer! Would I be able to use the JavaScript code to output the images with this? As I want this as a click event no a refresh :) thanks! – TheBiz Jul 12 '18 at 09:14
  • @TheBiz Yes, your click event should simply append an `` tag. – Brad Jul 12 '18 at 14:57
  • Does this look correct to you? I assume if I have got anything wrong it is the AJAX side of things https://imgur.com/a/96LrD4V Thankyou for your help brad :) – TheBiz Jul 13 '18 at 00:51
-1

You can use jQuery for a simple Ajax request:

<div class="boxa">A1
  <input id="rndimgbtn" type=button value="Display Random Image">
  <img id="rndimg" src="config.php" name="canvas" />
</div>

$("#rndimgn").click(function(){
  $.ajax({
    url: "./path/to/getmyrandomimage.php", 
    success: function(result){
      var data = $.parseJSON(result);
      $("#rndimg").attr("src", "data:"+data.mime+";base64,"+data.image});
    }
  });
});

And for the PHP:

#getmyrandomimage.php
$db = mysqli_connect("localhost","user","pass","autoselectdb");
$sql = "SELECT image, mime FROM table ORDER BY RANDOM() LIMIT 1";
$sth = $db->query($sql);
$result=mysqli_fetch_array($sth);

die(json_encode((object)[
  "image" => chunk_split(base64_encode($result['image'])),
  "mime" => $result['mime']
]));

Remember to store your images as normal blobs, not encoding or anything. You also need to store the image mime type, otherwise js don't know what image format its trying to render.

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
  • This is one of the most inefficient methods you could ever use. For one, you don't need this sort of API call at all. Two, base64 encoding adds about 34% overhead... needlessly. This is a bad solution. – Brad Jul 12 '18 at 02:04
  • I know, but it's what he requested. 1. `He stored the images as blobs.` 2. `I think the ajax side of things is confusing me the most.`, jQuery has simplistic requests, easy to understand. – Xorifelse Jul 12 '18 at 02:06
  • It doesn't matter that the images are blobs... your PHP script could simply return the binary data. And, AJAX is not required here at all. Your answer is bad. – Brad Jul 12 '18 at 02:06
  • `I am currently creating a program which displays random images from a click event.` ~> `And, AJAX is not required here at all.` Am I missing something here? – Xorifelse Jul 12 '18 at 02:14
  • Yes, you are. See my answer for details. – Brad Jul 12 '18 at 02:18