How to read filenames containing a number and only use those with less than or equal to a specified value, also how to make my 'cache' more efficient? - php

So I've got a couple of questions that I'm hoping someone will be able to help me with.
Firstly, I'm trying to create a page which parses information and organizes it by the hour into a table. At the moment my script parses the information with Simple HTML Dom and creates a text file for each hour called "hour_%time%.txt" (e.g. hour_02.txt, hour_14.txt, hour_22.txt). Each file will contain the parsed information as a table row.
How would I go about only using the files with times earlier than the current hour, so if the current hour was 9am, only files ending with equal to or less than 09 would be used? I was trying to use either explode or preg_match but I couldn't get it to work.
My code at the moment looks like so:
date_default_timezone_set('UTC');
$currentHour = date('H');
$cache_file = 'cache/hour_'.$currentHour.'.txt';
$data = '<tr><td>'.date('H:00').'</td><td>'.$firmato_count.'</td><td>'.$inviato_count.'</td><td>'.$positive_count.'</td><td>'.$negative_count.'</td></tr>';
file_put_contents($cache_file, $data);
echo '<table class="table"><tbody>';
echo '<tr><th>Time</th><th>Firmato</th><th>Inviato</th><th>Positive</th><th>Negative</th></tr>';
$files = glob("cache/hour_*.txt");
foreach($files as $txt){
$hourlyfile = file_get_contents($txt);
echo $hourlyfile;
}
echo '</table></tbody>';
And secondly, I'm fully aware this isn't the best way to do this but I couldn't figure out a better way myself. Can anyone suggest a more efficient way to store the parsed data and access it? Is it possible to use a single file? I did consider appending the same file however as my page will update frequently it ended up adding multiple lines of data for the same hour. Each file contains a string like so:
<tr><td>10:00</td><td>21</td><td>58</td><td>4</td><td>43</td></tr>
Any help is appreciated.

First convert your String of the hour to a number
[PHP]
$currentHour = intval($currentHour);
next compare
if($currentHour <= 9){ // < for less and <= for less and equal
doStuff
}

This only will display the file of the exact hour. Tell me if doesn't work for edit it.
date_default_timezone_set('UTC');
$currentHour = intval(date('H'));
$cache_file = 'cache/hour_'.$currentHour.'.txt';
$data = '<tr><td>'.date('H:00').'</td><td>'.$firmato_count.'</td><td>'.$inviato_count.'</td><td>'.$positive_count.'</td><td>'.$negative_count.'</td></tr>';
file_put_contents($cache_file, $data);
echo '<table class="table"><tbody>';
echo '<tr><th>Time</th><th>Firmato</th><th>Inviato</th><th>Positive</th><th>Negative</th></tr>';
$files = glob("cache/hour_*.txt");
if($currentHour == $currentHour){
foreach($files as $txt){
$hourlyfile = file_get_contents($txt);
echo $hourlyfile;
}
}
echo '</table></tbody>';

I ended up creating a variable called $globSearch and used if/elseif to create a search string based on the current hour. My code now looks like this:
date_default_timezone_set('UTC');
$currentDate = date('d/m/Y');
$currentHour = intval(date('H'));
$cache_file = 'cache/hour_'.$currentHour.'.txt';
$data = '<tr><td>'.date('H:00').'</td><td>'.$firmato_count.'</td><td>'.$inviato_count.'</td><td>'.$positive_count.'</td><td>'.$negative_count.'</td></tr>';
file_put_contents($cache_file, $data);
echo '<table class="table"><tbody>';
echo '<tr><th>Time</th><th>Firmato</th><th>Inviato</th><th>Positive</th><th>Negative</th></tr>';
if ($currentHour <= 9) {
$globSearch = "{cache/hour_[0][0-".$currentHour."].txt}";
} elseif ($currentHour >= 10 && $currentHour <= 19) {
$splitInt = str_split($currentHour);
$globSearch = "{cache/hour_[0][0-9].txt,cache/hour_[1][0-".$splitInt[1]."].txt}";
} elseif ($currentHour >= 20 && $currentHout <= 23) {
$splitInt = str_split($currentHour);
$globSearch = "{cache/hour_[0][0-9].txt,cache/hour_[1][0-9][2-".$splitInt[1]."].txt}";
}
//$files = glob("{cache/hour_[0][0-9].txt,cache/hour_[1][0-3].txt}", GLOB_BRACE);
$files = glob($globSearch, GLOB_BRACE);
foreach ($files as $txt) {
$hourlyfile = file_get_contents($txt);
echo $hourlyfile;
}
echo '</table></tbody>';
Thanks for replying Ruben and COOLGAMETUBE, much appreciated.

Related

How to run php file for only 10 times a day without cron?

I am new to php so please mind if it easy question. I have a php script, I want it to be executed only 10 times a day and not more than that. I don't want to use cron for this. Is there any way to do this in php only?
Right now I have set a counter which increases by one every time any one runs the script and loop it to 10 times only. if it exceeds it it shows an error message.
function limit_run_times(){
$counter = 1;
$file = 'counter.txt';
if(file_exists($file)){
$counter += file_get_contents($file);
}
file_put_contents($file,$counter);
if($counter > 11 ){
die("limit is exceeded!");
}
}
I want some efficient way to do this so everyday the script is only executed for 10 times and this is applicable for everyday i.e this counter gets refreshed to 0 everyday or is there any other efficient method.
I would rather recommend that you use a database instead - its cleaner and more simple to maintain.
However, it is achievable with file-handling as well. The file will be of format 2019-05-15 1 (separated by tab, \t). Fetch the contents of the file and split the values by explode(). Then do your comparisons and checks, and return values accordingly.
function limit_run_times() {
// Variable declarations
$fileName = 'my_log.txt';
$dailyLimit = 10;
$content = file_get_contents($fileName);
$parts = explode("\t", $content);
$date = $parts[0];
$counter = $parts[1] + 1;
// Check the counter - if its higher than 10 on this date, return false
if ($counter > $dailyLimit && date("Y-m-d") === $date) {
die("Daily executing limit ($dailyLimit) exceeded! Please try again tomorrow.");
}
// We only get here if the count is $dailyLimit or less
// Check if the date is today, if so increment the counter by 1
// Else set the new date and reset the counter to 1 (as it is executed now)
if (date("Y-m-d") !== $date) {
$counter = 1;
$date = date("Y-m-d");
}
file_put_contents($fileName, $date."\t".$counter);
return true;
}

PHP search array and return only first value that meets criteria

I have a directory of files that are labeled YYYY-MM-DD.jpg.
Using PHP, I am trying to search through an array of these files and print the filename (without the jpg) of the latest date that is before today.
For example: Today is 2015-04-14
Files:
2015-04-20.jpg <-in the future
2015-04-11.jpg <-first file that has a
date BEFORE today's date
2015-04-02.jpg
2015-04-01.jpg
I want to return "2015-04-11".
I've been working on this a couple days, trying to piece together things from multiple posts. So, I've gone through a lot of iterations. But here is one:
$scan = scandir($comic_path,1); //go through directory DESC
$last_comic = substr($scan[0],0,10); //substr scan to get just the date
function LastComic(){
foreach ($scan as $acomic) {
if ($acomic < $last_comic) {
echo $acomic . "\n";
}
$last_comic = $acomic;
}}
LastComic($last_comic);
Thanks in advance for any help.
Well, your code is in a good way:
$today = date("Y-m-d");
$last_comic = substr($scan[0],0,10);
foreach ($scan as $acomic) {
$only_date = substr($acomic,0,10);
if ($only_date < $today) {
$last_comic = $acomic;
break;
}
}
Is that what you're trying to accomplish?
This is pretty clean:
$scan = scandir($comic_path,1); //go through directory DESC
$last_comic = date('Y-m-d'); // today's date
foreach ($scan as $acomic) {
if (substr($acomic,0,10) < $last_comic) {
$last_comic = substr($acomic,0,-4);
echo "$last_comic\n";
break;
}
}

Reading only the last 10 lines of a text file "tail" (Jquery/Ajax/javascript or whatever)

I've been searching for solutions here for a long time now, and i haven't been able to find any so far
what i need is a way to read the last 10 or so lines of a text file, which continually updates every second
i've found some possible codes in php, but then i wont be able to update the file every second.
how do i get only the last 10 lines of a text file using some sort of javascript?
Try using array_slice, which will return a part of an array. In this case you want it to return the last 15 lines of the array,
$filearr = file("filename");
$lastlines = array_slice($filearr,-10);
You can change -10 (-10,-15 any value you want).
Hope it works!
Hmmm... maybe so, for large files:
$fileName = '[path_to_file]';
$file = new \SplFileObject($fileName);
$file->seek($file->getSize());
$lines = $file->key() - 1;
$file->setFlags(\SplFileObject::READ_CSV);
$counter = 0;
$records = 100;
$seek = $lines - $records;
$file->seek($seek);
$return = array();
while ($counter++ < $records) {
try {
$line = $file->fgets();
$return[] = $line;
} catch (\Exception $e) {
}
}
Didn't find the correct answer here, so i started a new question where i'm more specific with what i want
Reading ONLY the last 50 lines of a large text file

Change the order of pictures at midnight

I have a set of picture ads that I want to change the order of every day at midnight.
Basically so that one day it will be like this
<img src="image1">
<img src="image2">
<img src="image3">
<img src="image4">
and the next day it will look like this
<img src="image4">
<img src="image1">
<img src="image2">
<img src="image3">
How could I accomplish this with javascript, jquery or php. Not concerned about what language I use, just need to figure it out. Thanks..
Try this one http://jsfiddle.net/KQwf2/1/
HTML:
<img src="http://solarpanels2green.com/images/one.gif" title='1'>
<img src="http://solarpanels2green.com/images/two.gif" title='2'>
<img src="http://solarpanels2green.com/images/three.gif" title='3'>
<img src="http://solarpanels2green.com/images/four.gif" title='4'>
and js code
var all = $('img'),
shift = Math.floor(
(new Date().getTime() - new Date().getTimezoneOffset() * 60000)
/ (24 * 3600 * 1000)) % all.length;
all.filter(':gt(' + (all.length - shift - 1) + ')')
.insertBefore(all.first());
It calculates the MOD of the division of number of days passed since the midnight of January 1, 1970 by the number of the elements in the images list, takes this amount of images from the bottom of the list and moves them in front of the list.
Updated to take into account the timezone of the visitor.
If you have access to a database, it would be a simple matter in php to store the order each day in the database. Then when the page loads, you check the date that the order is from and update if it does not match the current date. The update process would consist of generating a new order through php's rand.
If you do not have access to a database, you will need to come up with a different randomization mechanism that is based solely around the date. One option would be to generate a hash of the date and use it to drive your ordering.
Here's some php pseudocode of the non-DB option:
$fullhash = md5(date("Ymd"));
$hash = $fullhash;
$countImages = 4; //or whatever the actual number of images you have is
$shownImages = array();
while ($countShown < $countImages)
{
$num = ord($hash); //get ascii value of first char of $hash
$num = $num % $countImages; //convert the number to something that corresponds to an image
if (!(in_array($num, $shownImages)))
{
echo "<img src='image" . $num . "'>";
$shownImages[] = $num;
}
$hash = substr($hash,1);
if (strlen($hash) == 0)
{
$fullhash = md5($fullhash); //generate a new hash in case the previous one did not catch all images
$hash = $fullhash;
}
}
This could seem overly complicated. If you can consistently set a seed for random number generation on your server, then you can replace most of the above code with that. However, more and more implementations are moving away from seed-it-yourself random number generators, which makes it less trivial to repeatably generate the same sequence of random numbers.
Here's one in PHP that only depends on the last-modification times of a set of images in a given directory:
<?php
function cmp($a, $b){
$atime = filemtime($a);
$btime = filemtime($b);
return $atime == $btime ? 0 : ($atime < $btime ? -1 : 1);
}
$paths = array();
if ($dh = opendir('images')){
while (($path = readdir($dh)) !== false){
if (substr($path, -4) == '.jpg'){
array_push($paths, "images/$path");
}
}
}
$count = count($paths);
$offset = time() % $count;
usort($paths, 'cmp');
for ($i = 0; $i < $offset; $i++){
$path = array_shift($paths);
array_push($paths, $path);
}
?>
Then, wherever you need it in your page:
<?php foreach ($paths as $path): ?>
<img src="<?php echo $path; ?>" ... />
<?php endforeach; ?>
you can get the time with javascript. then i would create an array, randomize the order and output your images
var d = new Date();
var time= d.getHours();
if(time>=24){
//code here for randomizing
}
http://www.w3schools.com/jsref/jsref_gethours.asp
http://www.javascriptkit.com/javatutors/randomorder.shtml

using do..while ,continue?

<?php
// initial value
$week = 50;
$year = 2001;
$store = array();
do
{
$week++;
$result = "$week/$year";
array_push($store,$result);
if($week == 53){
$week = 0;
$year++;//increment year by 1
}
continue;
}
// End of Loop
while ($result !== "2/2002");
?>
print_r($store);
result want return will be
array("51/2001", "52/2001", "01/2002", "02/2002");
What is my problems by using while using do..while ,continue?
Your arguments to array_push are the wrong way around. Read the manual entry for functions you use. Turn on warnings on your server; running this in codepad showed me the problem immediately. [Edit: You have now quietly fixed that in your question.]
You also have a typo: $i instead of $week.
Finally, you test against "02/2002", but for that month the string will be "2/2002".
Fixed code (live demo):
<?php
// initial value
$week = 50;
$year = 2001;
$store = array();
do
{
$week++;
$result = "$week/$year";
array_push($store, $result);
if($week == 53){
$week = 0;
$year++;//increment year by 1
}
continue;
}
// End of Loop
while ($result !== "2/2002");
?>
In general, I'd recommend against loops like this. As you've discovered, your code is very fragile because you're testing for just one very specific value, and if that value is not precisely correct you get an infinite loop.
Instead, consider comparing $week and $year separately and numerically:
while ($week < 2 && $year <= 2002)
Next time please include in your question the output that you are seeing, as well as the output that you want to see. It'll save us time in reproducing your problem.
I may not be understanding this correctly... If you could explain a bit more that'd help.
Try turning the loop into a function, and turn the while(..) to check the functions variable.
then just call it 4 times to fill your array.

Categories