View Full Version : {PHP} Display a different image at midnight every day
Brian07002
04-13-2018, 08:29 PM
Hello,
I have been searching every where for a php + mysql script that will display one "Pic of the day" image in my header from a folder. (NOT USING A WORDPRESS SITE)
Notes:
1. I am NOT using sequential images
2. I would like to have the script pick the images at random, never display the same image twice (until all images have been displayed)
3. Image must display all day until 12:00am (New York City timezone) before displaying the next image.
4. Images will be stored in a folder on my computer.
Can someone do this?
Brian07002
04-14-2018, 09:25 AM
Anyone?
jscheuer1
04-14-2018, 03:40 PM
Not sure how mysql would fit into this. When you say "4. Images will be stored in a folder on my computer." Is this live? Is 'my computer' the host? You can't expect anyone except you to see images on a local computer.
Also, when you say random AND not repeat. That's actually not random. What you perhaps want is to randomly pick an image each time, temporarily eliminate that image from the pool. Keep doing that until there are none left in the pool, and then start over again. Even doing it that way, it's possible that the last and the first image would be the same. The chance of that decreases the more images you have, but would still always be a possibility.
Brian07002
04-14-2018, 11:14 PM
Not sure how mysql would fit into this. When you say "4. Images will be stored in a folder on my computer." Is this live? Is 'my computer' the host? You can't expect anyone except you to see images on a local computer.
Also, when you say random AND not repeat. That's actually not random. What you perhaps want is to randomly pick an image each time, temporarily eliminate that image from the pool. Keep doing that until there are none left in the pool, and then start over again. Even doing it that way, it's possible that the last and the first image would be the same. The chance of that decreases the more images you have, but would still always be a possibility.
It's been quite some time since I have worked with php+mysql to do custom coding. But in any case, I require a php script that I can use to display a different image in my website header every day at 12 midnight. Can you help me accomplish that kind of php script? I have looked everywhere and can seem to find anything close to it at all.
Thank you
Brian
Brian07002
04-14-2018, 11:22 PM
Ok,
So can you make this php script: http://www.dyn-web.com/code/random-image-php/ change so it can display a different image every day at 12:00am (midnight) ? That is as close to what I am looking to do. Sorry but my php skills are very rusty, haven't been in this area for years. :(
Brian07002
04-15-2018, 12:57 AM
I think this will better explain what I want to do, sorry but the example below is copied from another website, I believe that code will display an image only at midnight...Which is what I want to do...
i
f( $date->format( 'H') == 0 && $date->format( 'i') == 0) {
echo "<img src="">";
}
For the <img src part, I want to use a url that will be stored in mysql db like: http://localhost/images/new_york.png
so the images folder is located at: http://localhost/images folder (hence, I am running a server on my computer)
Can you provide a php script that will take the php codes I provided and combine them so a random image script will change a different image a 12 midnight every night?
Sorry for my lack of knowledge in explaining.
Thank you
Brian
While this wouldn't take much code, I doubt you will find anyone willing to write and test something for you for free.
Here's how I would do this -
Add a date column to the table holding the urls. This column should allow a NULL value (indicates not used.)
1) On each page request query to find if there is a row in the table with a date that matches the current date.
1.a) If there is a matching row, retrieve the row and use the url to display the image. You should only store the filename.ext in the database, so that you can easily use the same script on any server and with any folder location for the images.
1.b) If there is no matching row, either the day changed or this is the first ever request.
1.b.1) Query to get the ids of the rows that have a NULL value in the date column.
1.b.1.a) If there are no matching rows, all the images have been used, UPDATE all the rows to change the date column to NULL, and go back to step 1.
1.b.1.b) If there are matching row(s), retrieve the ids, get one random id. UPDATE the matching row with the current date in the date column, and go back to step 1.
jscheuer1
04-15-2018, 09:27 PM
Great thinking DyDr! Love the way the date becomes a sort of delimiter. Still doesn't eliminate the possibility of a repeat image at the end/beginning of a new cycle. Using part of your logic and a few (or less) flat files. I think I can do that and eliminate the possible repetition. Still need to write it up though, as you say, a fair amount of work. We can put your multidimensional array into a flat file and work off of it, or save the date separately in its own file, and in any case use the file containing the image names to gradually whittle down the choices. A separate file could contain the current image name, it would be banned from the new array of images for the next cycle when that needs to occur. This could likely all be done in a single flat file though, just gets a little trickier.
jscheuer1
04-16-2018, 05:38 AM
OK, this seems to work very well in limited testing. Should be easily adapted to whatever (I have it write the source of an image tag, but it could write the background image of an element):
<!DOCTYPE html>
<html>
<head>
<title>Random Image Each Midnight</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<img src="
<?php
$path = "../site5/cssimages/scaled/"; // set path to images, include trailing slash
$imgfile = "images.txt"; // set path and filename to file to hold image names and current date, should not initially exist
$eol = PHP_EOL; // end of line reference
$date = date("zY", time()); // the current date as day number in the year, followed by the 4 digit year number
if(file_exists($imgfile)){$datedims = file($imgfile, FILE_IGNORE_NEW_LINES);}
else{$datedims = array();}
if (count($datedims) < 1 or (count($datedims) < 3 and $date !== $datedims[count($datedims) - 1])){ // it's the first time or we're beyond time and only one image is left
$imar = glob("$path{*.jpg,*.gif,*.png}", GLOB_BRACE); // grab images as array (include/exclude image patterns if/as desired)
if(count($datedims)){ // if this isn't the first time and the $imgfile hasn't been deleted
if(($key = array_search($datedims[0], $imar)) !== false){ // and the current image is still in the folder
unset($imar[$key]); // do not consider it in the next iteration
}
}
shuffle($imar); // random order for images (once shuffled will continue to be random until used up)
$imar[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $imar), LOCK_EX); // save for future use
$datedims = $imar; // use current $imar
}
else if ($date !== $datedims[count($datedims) - 1]){ // there're images left but we're past time
array_shift($datedims); // get rid of the first image listing
array_pop($datedims); // remove old outdated date
$datedims[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $datedims), LOCK_EX); // save for future use
}
echo $datedims[0]; // write result (first item now in the $datedims array)
?>
">
</body>
</html>
Let me know if there are any problems or questions.
Notes: Unless you have no possibility of the variables used here ever conflicting with other PHP code you're using or may use, the above PHP code should probably be encapsulated as a function, at which point $c could be used to economize on the usage of count($datedims) by setting it to that once $datedims is established, and utilizing it instead of the expression. array_splice() might be better than unset(), but is more cumbersome and the subsequent shuffle() restores sequential numeric keys (at least here), and doesn't (in testing) seem to be an issue, even if it didn't, though further changes might make that an issue. Not sure if LOCK_EX is required or even advisable, but seems to me as it should work out well in this scenario.
Brian07002
04-16-2018, 08:06 PM
OK, this seems to work very well in limited testing. Should be easily adapted to whatever (I have it write the source of an image tag, but it could write the background image of an element):
<!DOCTYPE html>
<html>
<head>
<title>Random Image Each Midnight</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<img src="
<?php
$path = "../site5/cssimages/scaled/"; // set path to images, include trailing slash
$imgfile = "images.txt"; // set path and filename to file to hold image names and current date, should not initially exist
$eol = PHP_EOL; // end of line reference
$date = date("zY", time()); // the current date as day number in the year, followed by the 4 digit year number
if(file_exists($imgfile)){$datedims = file($imgfile, FILE_IGNORE_NEW_LINES);}
else{$datedims = array();}
if (count($datedims) < 1 or (count($datedims) < 3 and $date !== $datedims[count($datedims) - 1])){ // it's the first time or we're beyond time and only one image is left
$imar = glob("$path{*.jpg, *.gif}", GLOB_BRACE); // grab images as array (include/exclude image patterns if/as desired)
if(count($datedims)){ // if this isn't the first time and the $imgfile hasn't been deleted
if(($key = array_search($datedims[0], $imar)) !== false){ // and the current image is still in the folder
unset($imar[$key]); // do not consider it in the next iteration
}
}
shuffle($imar); // random order for images (once shuffled will continue to be random until used up)
$imar[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $imar), LOCK_EX); // save for future use
$datedims = $imar; // use current $imar
}
else if ($date !== $datedims[count($datedims) - 1]){ // there're images left but we're past time
array_shift($datedims); // get rid of the first image listing
array_pop($datedims); // remove old outdated date
$datedims[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $datedims), LOCK_EX); // save for future use
}
echo $datedims[0]; // write result (first item now in the $datedims array)
?>
">
</body>
</html>
Let me know if there are any problems or questions.
Notes: Unless you have no possibility of the variables used here ever conflicting with other PHP code you're using or may use, the above PHP code should probably be encapsulated as a function, at which point $c could be used to economize on the usage of count($datedims) by setting it to that once $datedims is established, and utilizing it instead of the expression. array_splice() might be better than unset(), but is more cumbersome and the subsequent shuffle() restores sequential numeric keys (at least here), and doesn't (in testing) seem to be an issue, even if it didn't, though further changes might make that an issue. Not sure if LOCK_EX is required or even advisable, but seems to me as it should work out well in this scenario.
John,
First let me thank you so much for taking the time to code this up! I am very greatful for your experience in programming, I am one who truly does respect the work put out by you guys for all the countless hours you must have put into knowing what you do about computer programming. Thank you for that, really, Thank you!
Second, I do have an issue, that maybe you can help me resolve...I have done the following:
1. Copied / Pasted the code into a file called random.php
2. I created a images.txt file in which the image ulrs and dates will be written to. Gave it 755 permissions (Running Ubuntu 16.04 Linux, btw)
3. Update the path to my images folder (in which case I am using flags, so the folder is called flags)
I put the random.php in my /var/www/html (root folder on localhost)...I have the folder inside the root (/var/www/html/flags/) with the trailing back-slash, but when I run the random.php script, I get a (broken) icon of the image, image not showing . When I right mouse click on the broken image and select view image, the url is: http://localhost/1052018
Can you provide a solution?
Thanks again!
Brian
jscheuer1
04-16-2018, 09:44 PM
Well, i would want to know which version of PHP you're using. But the main thing I see right away is:
2. I created a images.txt file in which the image ulrs and dates will be written to. Gave it 755 permissions (Running Ubuntu 16.04 Linux, btw)
That file should not have been created. The script will do it for you. Creating it might or might not be a problem. The only other thing that might be an issue there I can think of is:
$path = "../site5/cssimages/scaled/"; // set path to images, include trailing slash
Make sure that points correctly to your image folder and that there are at least 5 images in there and that the trailing slash is used. Don't necessarily use the ../ prefix if that's not relevant on your system. It was on mine, that's the only reason it's there.
Further, the url you're seeing is the date convention I created (day 105, in the year 2018), so likely having created the file is the problem and/or the image folder is not correctly referenced. Delete your images.txt file, make sure the $path var is set correctly for your system, and try viewing the random.php page again. The permissions you set might be persisting and still be an issue. Hopefully, probably, not. As that file only needs to be accessed by the server.
If you want more help, please post your current code, your random.php file.
jscheuer1
04-17-2018, 03:36 PM
Please also read my previous message. But here's more information on the $path var. It must be relative to the page that the script is functioning on and it must point to a folder on the server. It cannot be an absolute or a network path. So if your images are in a folder named images that is a child folder of where the page is, it should be:
$path = "images/";
jscheuer1
04-17-2018, 09:23 PM
Oh, and also (please still read my previous two posts) file_put_contents (used by this code) requires PHP 5 or later. If you don't have that, I can work out something, already have a trial version for those who do not have file_put_contents.
Brian07002
04-18-2018, 10:27 PM
Here is my current code John as of 4-18-2018:
Hey John,
On a hunch, I went to try the script...When I first ran the test (just a few seconds ago) the script was complaining about the images.txt file...Then I created that file in the flags folder with the images, and refreshed and the code works, it's displaying one flag! The only thing is I would love to each image to have a different link (url)...I guess I just had to put the images.txt file in the same folder as the images...Unless the path to the images.txt was incorrect, but in any case the code now works (coincidently)...
I have advanced my clock by setting the time in the taskbar to manual then using:
date +%T -s "23:59:50" and waiting 10 seconds then hitting refresh, and wa-la, we have success!
Here's the code:
<!DOCTYPE html>
<html>
<head>
<title>Random Image Each Midnight</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<img src="
<?php
$path = "flags/"; // set path to images, include trailing slash
$imgfile = "flags/images.txt"; // set path and filename to file to hold image names and current date, should not initially exist
$eol = PHP_EOL; // end of line reference
$date = date("zY", time()); // the current date as day number in the year, followed by the 4 digit year number
if(file_exists($imgfile)){$datedims = file($imgfile, FILE_IGNORE_NEW_LINES);}
else{$datedims = array();}
if (count($datedims) < 1 or (count($datedims) < 3 and $date !== $datedims[count($datedims) - 1])){ // it's the first time or we're beyond time and only one image is left
$imar = glob("$path{*.png}", GLOB_BRACE); // grab images as array (include/exclude image patterns if/as desired)
if(count($datedims)){ // if this isn't the first time and the $imgfile hasn't been deleted
if(($key = array_search($datedims[0], $imar)) !== false){ // and the current image is still in the folder
unset($imar[$key]); // do not consider it in the next iteration
}
}
shuffle($imar); // random order for images (once shuffled will continue to be random until used up)
$imar[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $imar), LOCK_EX); // save for future use
$datedims = $imar; // use current $imar
}
else if ($date !== $datedims[count($datedims) - 1]){ // there're images left but we're past time
array_shift($datedims); // get rid of the first image listing
array_pop($datedims); // remove old outdated date
$datedims[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $datedims), LOCK_EX); // save for future use
}
echo $datedims[0]; // write result (first item now in the $datedims array)
?>
">
</body>
</html>
Brian
jscheuer1
04-18-2018, 11:40 PM
Great! So it's working. I was very excited too when I saw it working as expected.
OK, just finishing up dinner here, may be busy for a bit. But I already have a good idea how to adapt this to utilize the associative array you must have created for the other thread that relates to this. First I will want to review the code you're using to see anything additional it can tell me, second I have updated code that's more foolproof/compatible with other code, but that's not necessary if what you have works, finally I'll present how the associative array and links can be worked in with both what you have, and the more recent code I've been using (incidentally it's already working fine here and on my live server as well).
jscheuer1
04-19-2018, 02:16 AM
OK, best I can figure is it was the permissions set on the original images.txt file and/or the fact that you created it - I could have been clearer about that. The server needs read write privileges on that file. And it cannot exist until the script creates it. If you know what you're doing or have some idea, you can edit it later for testing purposes, but never allow it to have only one line in it, and never remove the last line (the numeric date line). As long as you don't set permissions on it (just let the server decide as it creates and maintains it), you can always just delete it if you run into problems or want to change the the images in the flags folder. You can change them and not worry as long as they still have the same names. But if you add or remove images or change their names, you should delete the images.txt file and it will start over on its own. You should be able to use this new code without deleting your existing images.txt file. But you should be able to delete it at any time for testing purposes/whatever. Now, I've tested this as best as I think I can here. And you will have to edit the $links array (near the end - probably just use the same one you created for the other code), as I have no idea of the names of your image files or the pages associated with them. Otherwise, this should be a drop in replacement for what you just posted that's already working (save the the working version as a backup, just in case):
<!DOCTYPE html>
<html>
<head>
<title>Random Image Each Midnight</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<a href="<?php
// MidnightRambler PHP Script (c)2018 John Davenport Scheuer
// as first seen in http://www.dynamicdrive.com/forums/
// username: jscheuer1 - This Notice Must Remain for Legal Use
function midnightrambler(){ // requires PHP 5 or greater
$path = "flags/"; // set path to images, include trailing slash, must be on the server AND relative to the current page
$imgfile = "flags/images.txt"; // set path and filename to a non-existing file to hold image names and current date, DO NOT CREATE THIS FILE!
$eol = PHP_EOL; // end of line reference
$date = date("zY", time()); // the current date as day number in the year, followed by the 4 digit year number
if(file_exists($imgfile)){$datedims = file($imgfile, FILE_IGNORE_NEW_LINES);}
else{$datedims = array();}
$c = count($datedims);
if ($c < 2 or ($c < 3 and $date !== $datedims[$c - 1])){ // it's the first time, file was edited improperly/deleted, or we're beyond time and only one image is left
$imar = $imar = glob("$path*.[Pp][Nn][Gg]"); // grab images as array (include/exclude image patterns if/as desired)
if($c > 1){ // if this isn't the first time and the $imgfile hasn't been deleted
if(($key = array_search($datedims[0], $imar)) !== false){ // and the previous image is still in the folder
array_splice($imar, $key, 1); // do not consider it in the next iteration
}
}
shuffle($imar); // random order for images (once shuffled will continue to be random until used up)
$imar[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $imar), LOCK_EX); // save for future use
$datedims = $imar; // use current $imar
}
else if ($date !== $datedims[$c - 1]){ // there's images left but we're past time
array_shift($datedims); // get rid of the first image listing
array_pop($datedims); // remove old outdated date
$datedims[] = $date; // add the current date to the array for checking later
file_put_contents($imgfile, implode($eol, $datedims), LOCK_EX); // save for future use
}
$im = $datedims[0];
$links = array("dragonfly-2257281_1280.jpg" => "http://www.google.com/", // change these to reflect your filenames and links
"bird-2252045_1280.jpg" => "http://www.dynamicdrive.com/");
echo $links[basename($im)] . '"><img src="' . $im . '" alt="Flag'; // write result (first item now in the $datedims array)
}
midnightrambler();
?>
"></a>
</body>
</html>
Notes: There are changes both within and without the PHP code block, so just copy and use this as is, except of course for entering your own $links array. I changed the GLOB expression to eliminate GLOB_BRACE, as it's not really used in your setup, and added a GLOB convention that makes its testing of the extension case insenitive, just in case that ever becomes an issue. I've changed some comments to make some things clearer, hopefully and done some of the things I mentioned earlier - encapsulation to protect it from other code and to protect other code from it, and (because it was now safe to do so) used the $c variable to conserve on the count($datedims) expression. I've also added a credit, which is not mandatory, but since no one but you or other web masters will see it, all it will do is remind one where to come for help later. BTW, though it might not matter, the permissions on my images.txt (automatically generated by the server) are 644. I think part (possibly all) of the problem may have been my logic in analyzing the length of the $datedims array. I've tried to correct that in the current version. However, clearly, a text file never needs execute permission for any of the three possible entities, so that may have entered into it. Still, I think the error was more likely mine in not correctly bringing logic to bear on the length of the $datedims array. It would work in ideal conditions, but not when mistakes entered in. That's tightened up now I think. Perhaps other things can be done, not sure at the moment.
Any problems or questions, just let me know.
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.