PHP Script ,php://input check for empty File - php

Hello i need help with my PHP script.
The Upload function works great, but many files are empty.
Can you help me please to check first IF file is empty or < 1 byte. and Ignore them.
<?php
$vist_page = "post2.php";
include "logger.php";
file_put_contents("outputfile.txt".uniqid(), file_get_contents("php://input"));
?>
Thanks ;)

One way to do that would be to use strlen() to check the length of the string, which could be done by replacing
file_put_contents("outputfile.txt".uniqid(), file_get_contents("php://input"));
with
$content = file_get_contents("php://input");
if (strlen($content)) {
file_put_contents("outputfile.txt".uniqid(), $content);
}
else {
// Your error response here
}

$filename = 'somefile.txt';
if (filesize($filename) < 1) {
//ignore
} else {
//do stuff here
}
filesize returns the file size in bytes
https://www.php.net/manual/en/function.filesize.php
this may be more effecient:
$filename = 'somefile.txt';
if (filesize($filename) > 0) {
//do stuff here
}

Related

Retaining indentation with file_get_contents

I'm fetching html code using the code below, it works without any problem, the only issue is the indented code isn't retained
for example the fetched code looks like:
<div>
data
</div
instead of
<div>
data
</div>
php:
<?php
function getFile($file)
{
if (file_exists($file)) {
$file = file_get_contents($file);
return $file;
} else {
return false;
}
}
I understand it isn't an "issue" but if it's possible to retain the correct indent code I'd like to, thank you.
Your current code does retain the indentation, if you want more indentation then this is just an example using your code. You could use spaces as shown or a tab.
Call it with $indent as the number of spaces that you want to add:
function getFile($file, $indent=false)
{
if (file_exists($file)) {
if($indent) {
$i = (str_repeat(' ', $indent);
$file = $i . implode($i, file($file));
} else {
$file = file_get_contents($file);
}
return $file;
} else {
return false;
}
}
An alternative would be to create an indent() function and then in the above just call it:
$file = indent(file_get_contents($file), 4);
It might be a content type encoding issue. file_get_contents will read the file contents using the default charset as configured in php.ini at setting default_charset, which is UTF-8 by default.
We can use mb_detect_encoding to ensure that it is the same as the default character set, if not we have the option to convert it to the detected encoding with mb_convert_encoding.
<?php
function getFile($file) {
if (file_exists($file)) {
$file = file_get_contents($file);
$detect_enc = mb_detect_encoding($file);
if ($detect_enc != ini_get('default_charset'))
$file = mb_convert_encoding($file, $detect_enc);
return $file;
} else {
return false;
}
}
nJoy!
Just a random guess: you probably have output of few spaces somewhere in your code before you output file content to the client.
To avoid that you need to clean output. You can do that inside this getFile() function:
function getFile($file)
{
if (file_exists($file)) {
$file = file_get_contents($file);
ob_clean(); // <-- clean the output if any happened before
return $file;
} else {
return false;
}
}
Or outside where you call it I guess something like:
...
ob_clean();
echo getFile($file);

How to read and write to a file, ensuring file is locked?

I am looking to numerically increment to a file's content if the file was last modified within 24 hours otherwise reset the file's content to 1. However I want to ensure this continues to work regardless of how many users visit the script at the same time (the script would always need to execute but ensure it does not overwrite/calculate incorrectly - I believe this is where flock comes to use).
Please see below code:
$host_limit = 50;
$file = 'timer.txt';
$fh = fopen($file,'r+');
if (flock($fh,LOCK_EX)) {
$content = fgets($fh);
//FILE HAS NOT BEEN MODIFIED IN LAST 24 HOURS
if (strtotime('-24 hours') > filemtime($file)) {
$content = 1;
} else {
$content = ($content + 1);
}
fwrite($fh, $content);
fflush($fh);
flock($fh,LOCK_UN);
}
fclose($fh);
if ($content < $host_limit) {
//do stuff
}
Would the above work as I would like (as have no way to simulate what I am anticipating to test)?
Instead of using fopen and fwrite, you could use
file_get_contents($file);
and
file_put_contents($file, $content, LOCK_EX);
Check the manual:
http://php.net/manual/en/function.file-get-contents.php
http://php.net/manual/en/function.file-put-contents.php

PHP: How to constantly read a file

I need to read a file that is changing all the time. the file only and will only ever have one line that changes all the time.
I found the following code that should do what I want here: PHP: How to read a file live that is constantly being written to
But the code does not work, the page just keeps loading, I tried to add a "flush" like one user suggested, but I still cant make it work.
Here's the code
$file='/home/user/youfile.txt';
$lastpos = 0;
while (true) {
usleep(300000); //0.3 s
clearstatcache(false, $file);
$len = filesize($file);
if ($len < $lastpos) {
//file deleted or reset
$lastpos = $len;
}
elseif ($len > $lastpos) {
$f = fopen($file, "rb");
if ($f === false)
die();
fseek($f, $lastpos);
while (!feof($f)) {
$buffer = fread($f, 4096);
echo $buffer;
flush();
}
$lastpos = ftell($f);
fclose($f);
}
}
Please could someone have a look and let me know how to fix it.
Thanks in advance.
If your file have only one string, and you need to read it on change, use this code:
$file = '/path/to/test.txt';
$last_modify_time = 0;
while (true) {
sleep(1); // 1 s
clearstatcache(true, $file);
$curr_modify_time = filemtime($file);
if ($last_modify_time < $curr_modify_time) {
echo file_get_contents($file);
}
$last_modify_time = $curr_modify_time;
}
Note:
filemtime() returns last file modification time in seconds, so if you need to check modification more than one time per second, probably you'll need to find other solutions.
Also, you may need to add set_time_limit(0); it depends on your requirements.
Update:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
type="text/javascript">
</script>
</head>
<body>
<div id="file_content"></div>
<script>
var time = 0;
setInterval(function() {
$.ajax({
type: "POST",
data: {time : time},
url: "fileupdate.php",
success: function (data) {
var result = $.parseJSON(data)
if (result.content) {
$('#file_content').append('<br>' + result.content);
}
time = result.time;
}
});
}, 1000);
</script>
</body>
fileupdate.php
<?php
$file = 'test.txt';
$result = array();
clearstatcache(true, $file);
$data['time'] = filemtime($file);
$data['content'] = $_POST['time'] < $data['time']
? file_get_contents($file)
: false;
echo json_encode($data);
You might be dealing with 3 drawbacks:
First, the code you already have is holding a $lastpos. Meaning, it will always look for what is added at the end of the file. You are not clear in the OP, but I think this is not what you want. I think your one and only line is continuously changing, but not necessarily changing size. So you might want to remove the line $lastpos = ftell($f);.
Secondly, in regards to the same, you are check the file size to know if the file has changed. But as I explained, the file might have changed, while the file size stayed equal. Try changing the check of the file size to checking the file last-edit date.
Third, and probably most importantly: your web browser might be buffering your output until the php script is done running, before it releases the buffered output to the browser. Disable output buffering in both PHP and your web server. Things like gzip/compression by the web server can also be forcing output-buffering effects.

PHP not writing to file from one source

I have an issue I can't seem to find the solution for. I am trying to write to a flat text file. I have echoed all variables out on the screen, verified permissions for the user (www-data) and just for grins set everything in the whole folder to 777 - all to no avail. Worst part is I can call on the same function from another file and it writes. I can't see to find the common thread here.....
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
if (!$Handle = fopen($File, 'w')) {
return "Cannot open file ($File)";
exit;
}/*
if(!flock($Handle, LOCK_EX | LOCK_NB)) {
echo 'Unable to obtain file lock';
exit(-1);
}*/
if (fwrite($Handle, $NewContents) === FALSE) {
return "Cannot write to file ($File)";
exit;
}else{
return $NewContents;
}
}else{
return "<p align=\"center\">There was an issue saving your settings. Please try again. If the issue persists contact your provider.</p>";
}
}
Try with...
$Handle = fopen($File, 'w');
if ($Handle === false) {
die("Cannot open file ($File)");
}
$written = fwrite($Handle, $NewContents);
if ($written === false) {
die("Invalid arguments - could not write to file ($File)");
}
if ((strlen($NewContents) > 0) && ($written < strlen($NewContents))) {
die("There was a problem writing to $File - $written chars written");
}
fclose($Handle);
echo "Wrote $written bytes to $File\n"; // or log to a file
return $NewContents;
and also check for any problems in the error log. There should be something, assuming you've enabled error logging.
You need to check for number of characters written since in PHP fwrite behaves like this:
After having problems with fwrite() returning 0 in cases where one
would fully expect a return value of false, I took a look at the
source code for php's fwrite() itself. The function will only return
false if you pass in invalid arguments. Any other error, just as a
broken pipe or closed connection, will result in a return value of
less than strlen($string), in most cases 0.
Also, note that you might be writing to a file, but to a different file that you're expecting to write. Absolute paths might help with tracking this.
The final solution I ended up using for this:
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
return $NewContents;
}else{
return "<p align=\"center\">There was an issue saving your settings.</p>";
}
}
function WriteNewConfigToFile($File2WriteName, $ContentsForFile){
file_put_contents($File2WriteName, $ContentsForFile, LOCK_EX);
}
I did end up using absolute file paths and had to check the permissions on the files. I had to make sure the www-data user in Apache was able to write to the files and was also the user running the script.

Getting syntax error while using fopen and fread

$file = "status.txt";
$open = fopen($file, "r");
$size = filesize($file);
$count = fread($open, $size);
if($count == 1) {
header('Location: http://www.google.com/');
} else {
echo "Status is unavailable";
}
Hello, I am trying to read a text file.
I get the error Parse error: syntax error, unexpected T_STRING while doing this.
I am trying to read status.txt and if it has 1 it will redirect else it will say Status is unavailable.
Any ideas?
I must point out that for simple files like this, that file_get_contents is much easier than fopen, fread, fclose (which you omitted), etc.
The code that you posted does not appear to have any issues by itself. Perhaps you messed something up before that whole block? Try and comment things out to isolat the bug. This is a debugging skill you will need to acquire.
The error is not in those lines for sure! please include the whole PHP script, there're must be something wrong before or after those lines.
Please try this code out!
<?php
$file = 'status.txt';
$contents = file_get_contents($file);
if ((strlen($contents)-1) == 1) {
header('Location: http://www.google.com');
} else {
echo 'Status is unavailable';
}
?>
The (-1) in the compression because of the new line character count at the last line.
If you're talking about the content of "status.txt" please put the '1' between quotes. if it is just a TRUE or FALSE statement just use if($count){ ... }else{ ...}

Categories