Appending multiple entries to an output file with a crontab using php? - php

I am writing a script in PHP in which I had to write the system uptime, the current time, and the amount of users logged in the system into a log file, and be updated continually via a crontab.
What I need help with is that I would like the updates to accumulate within the file and be added continually. So far, whenever my script gets executed, the newest update overwrites the previous update.
What I've done is that I tried to declare an array of entries and as I iterate through the array push the contents of the update into the array (It might be a bit of half-baked logic on my part).
My Code:
$fileName = '../so-and-so directory/output.log';
$dt = date('m/d/y');
$time = date('h:i A');
$data = shell_exec('uptime');
$uptime= explode(' up ', $data);
$uptime = explode(', ', $uptime[1]);
$uptime = $uptime[0].','.$uptime[1];
$users = system('w', $who);
$array = new SplFixedArray(3);
$fileLog = fopen($fileName, 'w');
$fileString = "Date: ".$dt. "\n". " Time: ".$time . "\n".
"System uptime ". $uptime ."\n" ."Users " . $users;
foreach ($array as $entry) {
array_push(file_put_contents($fileName, $fileString));
}
fclose($fileLog);
I feel that the solution is very simple but I'm missing it. Would somebody please clue me in?

The "w" filemode truncates the file on open. "a" appends to the end instead. See fopen(3) or the PHP documentation for details.
Also, file_put_contents() is destroying the file. Try fwrite() instead.

drop fopen; simply use
file_put_contents($fileName, $fileString);
file_put_contents will overwrite the existing file by default.
In short:
$fileName = '../so-and-so directory/output.log';
$dt = date('m/d/y');
$time = date('h:i A');
$data = shell_exec('uptime');
$uptime= explode(' up ', $data);
$uptime = explode(', ', $uptime[1]);
$uptime = $uptime[0].','.$uptime[1];
$users = system('w', $who);
$fileString = "Date: ".$dt. "\n". " Time: ".$time . "\n".
"System uptime ". $uptime ."\n" ."Users " . $users;
file_put_contents($fileName, $fileString);

So it turns out that I needed to edit my crontab file as such:
* * * * * such-and-such-script.php >> ../so-and-so directory/output.log 2>&1
To make them append without the previous one being overwritten by the new one. I also lost the fopen() and instead of doing file_put_contents, I did fwrite() into the file. It works great now. Thank you!

Related

Problem with exploding text file, using file function

function dailyStat(){
$data = "";
$currentTime = time();
$file = file("data/pageStat.txt");
foreach ($file as $row) {
$row = trim($row);
$values = explode("\t", $row);
$loginTime = getTime($values[1], $values[2]);
if ($currentTime - $loginTime <= 84000){
$data.=$row;
}
}
$stat = fopen("data/pageStat.txt", "w");
fwrite($stat, $data);
fclose($stat);
}
function getTime($givenDate, $givenTime){
$date = explode(".", $givenDate);
$time = explode(":", $givenTime);
$hour = intval($time[0]);
$minute = intval($time[1]);
$second = intval($time[2]);
$day = intval($date[0]);
$month = intval($date[1]);
$year = intval($date[2]);
return mktime($hour, $minute, $second, $month, $day, $year); }
Heloo, I have following problem. I want to make a stat page about visits by page on my website in last 24h, but I have problem. Every visit on any page is written in txt file. I showed two functions here, dailyStat() - it should show only visits in last 24 hours, and getTime() - it should find utc from time i txt file.
/biznews/index.php?page=index 05-06-2022 00:24:57 192.163.50.1
This is the exaple of one row in txt file, every column is separated by \t and every row is separated by \n. The problem is that I always get error Undefined array key 1, Undefined array key 2. But I know that those array keys exist because I exploded them. Can someone help, because I don't know what is happening. Note: all paths are correctly.
This practice is highly unsecure and with a simple bot which makes some thousands of requests to your site your server and your hosting account would be banned and down because you can easily consume all inodes in the host file system.
Make a new file for every request is a bad bad bad idea.
Why don't you use Monolog or other package which is easy to use and have an almos perfect implementation of logging facilities.
Use composer and follow https://www.loggly.com/ultimate-guide/php-logging-libraries/
If you need to parse logs you could https://github.com/pulse00/monolog-parser

Trying to change all image file names in a folder to the date and time image was taken

I have a folder of images that I am trying to change to be the date and time the picture was taken. I managed to make it work for the most part, however if the image has the same DateTimeOriginal (to the second), the subsequent images are deleted and replaced with the last one. This is a problem when I use burst on my camera.
I am trying to have the code add "_1" after each file name, unless the file name exists, then I want the "_1" to increase by 1. So far, the code I have will catch the first duplicate name and work properly, but every other matching filename after just deletes the file before it that has the same name (which was just renamed by the code).
In case it makes a difference, I am using XAMPP to run the PHP code in a local directory on my windows 10 PC, but I do test it online as well and have the same outcome.
The following is the code I have come up with by piecing together other code that I have found, and then attempting to customize it. I have a general understanding of PHP through trial and error, but have no education. I feel like I should be using a "while" statement while(file_exists('pictures/'.$timestamp.'_'.$count.'.jpg')) instead of or in conjunction with the current if statement I have if (file_exists('pictures/'.$timestamp.'_'.$count.'.jpg'))
The entire code I am using is here:
<?php
$count=1;
$handle = opendir(dirname(realpath(__FILE__)).'/pictures/');
while($file = readdir($handle)){
if($file !== '.' && $file !== '..'){
date_default_timezone_set('America/Edmonton');
$dirloc = "pictures/$file";
$newdirloc = "NewPictures/$file";
$exif_data = exif_read_data ($dirloc, $file, 0, true);
$exifString = $exif_data['DateTimeOriginal'];
$exifPieces = explode(":", $exifString);
$newExifString = $exifPieces[0] . "-" . $exifPieces[1] . "-" . $exifPieces[2] . ":" . $exifPieces[3] . ":" . $exifPieces[4];
$exifTimestamp = strtotime($newExifString);
$timestamp = date("y-m-d_H-i-s", $exifTimestamp);
if (file_exists('pictures/'.$timestamp.'_'.$count.'.jpg')) {
$ExistingFile = 'pictures/'.$timestamp.'_'.$count.'.jpg';
$delimiters = ['-', '_', '.'];
$newStr = str_replace($delimiters, $delimiters[0], $ExistingFile);
$NamePieces = explode("-", $newStr);
$count = $NamePieces[6];
++$count;
echo ($file.' has now been changed to '.$timestamp.'_'.$count.'.jpg (Increased count from existing file)<br>');
rename('pictures/'.$file, 'pictures/'.$timestamp.'_'.$count.'.jpg');
}
else {
echo ($file.' has now been changed to '.$timestamp.'_1.jpg (Unique File)<br>');
rename('pictures/'.$file, 'pictures/'.$timestamp.'_1.jpg');
}
}
}
?>
Thanks for helping this newbie figure this out!
Edit:
I think I've narrowed it down to a simpler question.
If it is possible to see if $ANY_NUMBER is in fact any number, what would I say $ANY_NUMBER is = to? With this change, I should be able to get rid of the count=1 at the start, and if it is true that it is any number in that [6] spot, than I should be able to say that count= that [6] spot. Does that make sense?
if (file_exists('pictures/'.$timestamp.'_'.$ANY_NUMBER.'.jpg')) {
$ExistingFile = 'pictures/'.$timestamp.'_'.$ANY_NUMBER.'.jpg';
$delimiters = ['-', '_', '.'];
$newStr = str_replace($delimiters, $delimiters[0], $ExistingFile);
$NamePieces = explode("-", $newStr);
$count = $NamePieces[6];
++$count;
echo ($count);
}

PHP 7.1 "require/include" result is not up to date

I have a file containing:
<?php
return '2000-01-01 00:00:00';
?>
and I have this code:
<?php
$oldValue = require 'file.php';
$now = new DateTime();
$handle = fopen('file.php', "w");
fputs($handle, "<?php\nreturn '" . $now->format('Y-m-d H:i:s') . "';");
fclose($handle);
$newValue = require 'file.php';
echo "Old value: $oldValue ";
echo "New value: $newValue ";
?>
The output with PHP 5.3 is:
Old value: 2000-01-01 00:00:00 New value: 2018-03-28 10:33:12
The output with PHP 7.1 is:
Old value: 2000-01-01 00:00:00 New value: 2000-01-01 00:00:00
In the two cases, the string in the file changes.
Can some one help me to update the new value with PHP 7.1?
Note: it's not the real problem. It's just an abstraction of the problem to make things more simple and comprehensible. So please, no lessons of PHP best practices. I just like to get a good response to my question.
Thanks :)
As commented by iainn The issue is that the PHP server is caching the file once it's loaded and is not re-calling the file from disc on the second require, instead calling it from it's memory cache.
As you have stated that:
"the content of the file changes "
then the issue is the new contents are not passed to the script, instead using the memory of the older contents.
Therefore call clearstatcache() to force clear the cached file data. This should be placed after the new data is written to update the file, and before the file is called for a second time.
If this does not work then the file data may be cached elsewhere in its route.
<?php
$oldValue = require 'file.php';
$now = new DateTime();
$handle = fopen('file.php', "w");
fputs($handle, "<?php\nreturn '" . $now->format('Y-m-d H:i:s') . "';");
fclose($handle);
clearstatcache(); // THIS line should help you
$newValue = require 'file.php';
echo "Old value: $oldValue ";
echo "New value: $newValue ";
?>
As also commented by iainn opcache_invalidate()may be a more specific/less general solution for you.
It could be an issue with your file being cached (OPcache) and php returning the same file in both require calls
Can you try modifying opcache settings
opcache.enable = 0
and then testing it ? Also there is
opcache_reset()
could help you but if you running your code from CLI it may not work.

Auto cut on thermal printer (php)

How can i perform auto cut on Epson TMT82 from PHP File? bellow is my config file.
Config:
$tmpdir = sys_get_temp_dir();
$file = tempnam($tmpdir, 'ctk');
$handle = fopen($file, 'w');
$condensed = Chr(27) . Chr(33) . Chr(4);
$bold1 = Chr(27) . Chr(69);
$bold0 = Chr(27) . Chr(70);
$initialized = chr(27) . chr(64);
$condensed1 = chr(15);
$condensed0 = chr(18);
$Data = $initialized;
$Data .= $condensed1;
Printing:
fwrite($handle, $Data);
fclose($handle);
copy($file, "//localhost/printer"); # printing
unlink($file)
Try to write chr(29) + 'V' (or chr(86)), and then the values for m and n, depending on the exact function you want to use as per the manual below (if you just want to cut without feeding at all, you want to use function A, which means you can just follow with a 0 (or 48, not sure why they mentioned both numbers in the manual...!?), like so:
chr(29) . "V" . 0
https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=87
(you need to be logged on to read this reference, but registering is free)
Edited: the chr() code for 'V' is 86, not 56
Edit2: Just to comment on what Matt Gibson said; chr(27) . chr(105) should also work on your model (just checked, also chr(27) . chr(109)), but it's an obsolete command, you should be using chr(29) . "V". In any case, some printers like to receive these sorts of commands on their own instead of having them along with the rest of the string.
Once you get this right, you should probably define a variable with the type of cut that you want. Ex. $cutPaper = chr(29) . "V" . 0;

How to operate txt file on PHP?

I have txt file, which keeps 1 as in the following query to take the contents from txt and +1
function analitic(){
$file = fopen(TEMPLATEPATH . "/analitic.txt", "w");
$txt = $_POST['data']; //$txt = 1
fwrite($file, $txt);
fclose($file);
}
And how to add a date in the txt file? And if the date is different, save the data in the next line?
Thank you google translate :)
This will work...
file_put_contents(TEMPLATEPATH."/analitic.txt",PHP_EOL.date('c').PHP_EOL,FILE_APPEND);
PHP_EOL - this the "next line" character
file_put_contents / FILE_APPEND is a slightly more concise method of writing to a file
'c' - is the date format for an ISO date time, please see http://php.net/manual/en/function.date.php for more information
Some think like this:
function my_action_myFunc(){
$data = $_POST['data'];
$date = date('d.m.Y');
$file = file_get_contents(TEMPLATEPATH."/analitic.txt",null,null, 10);
settype($file, "integer");
settype($data, "integer");
$a = $file+$data;
file_put_contents(TEMPLATEPATH."/analitic.txt",$date.PHP_EOL.$a);
wp_die();
}

Categories