php - feof error - php

The file that I'm trying to read is a pgp-encrypted file. This is part of the process to decrypt it and I'm actually attempting to read the contents into a string so that I can then decrypt it. I'm not sure if that's the core problem here or not, but I'm getting an error:
Warning: feof(): supplied argument is not a valid stream resource
Here's the file code:
if($handle = opendir($dir)) {
while( false !== ($file = readdir($handle))) {
if($file != "." && $file != "..") {
$fhandle = fopen($file, "r");
$encrypted = '';
$filename = explode('.',$file);
while(!feof($fhandle)) {
$encrypted .= fread($fhandle, filesize($file));
}
fclose($fhandle);
$decrypted = $filename[0].'.txt';
shell_exec("echo $passphrase | $gpg --passphrase-fd 0 -o $decrypted -d $encrypted");
}
}
}

Learn to debug your code.
supplied argument is not a valid stream resource means passed variable contains unexpected value. So, we can make a logical conclusion, that a function returning this variable had fail.
So. we have to check fopen($file, "r"); what makes it fail? may be we can check if a file exists? And so on.
This is called debugging and you cannot program without it.
Though it seems very strange.
Because fopen should throw an error as well.

You should check the fopen call to make sure you're file has actually been opened. Check it's return value.
As for fixing it you're working directory is likely different than $dir. You probably need
fopen("$dir/$file","r");
unless you change to the directory first.
edit clarified that the code sample was a possible solution to the problem, not code to check the return value.

You need to check your return values. The error indicates that $fhandle doesn't contain a valid file handle - it probably contains false, which fopen returns on failure.
See http://ca.php.net/manual/en/function.fopen.php

Related

My php script won't open files that aren't in its root directory

This is a php script for a user login system that I am developing.
I need it to read from, and write to, the /students/students.txt file, but it won't even read the content already contained in the file.
<?php
//other code
echo "...";
setcookie("Student", $SID, time()+43200, "/");
fopen("/students/students.txt", "r");
$content = fread("/students/students.txt", filesize("/students/students.txt"));
echo $content;
fclose("/students/students.txt");
fopen("/students/students.txt", "w");
fwrite("/students/students.txt", $content."\n".$SID);
fclose("/students/students.txt");
//other code
?>
You are not using fopen() properly. The function returns a handle that you then use to read or edit the file, for example:
//reading a file
if ($handle = fopen("/students/students.txt", "r"))
{
echo "info obtained:<br>";
while (($buffer = fgets($handle))!==false)
{ echo $buffer;}
fclose($handle);
}
//writing/overwriting a file
if ($handle = fopen("/students/students.txt", "w"))
{
fwrite($handle, "hello/n");
fclose($handle);
}
Let me know if that worked for you.
P.S.: Ty to the commentators for the constructive feedback.
There are many ways to read/write to file as others have demonstrated. I just want to illustrate the mistake in your particular approach.
fread takes a file handle as param, NOT a string that represents the path to the file.
So your line:
$content = fread("/students/students.txt", filesize("/students/students.txt")); is incorrect.
It should be:
$file_handle = fopen("/students/students.txt", "r");
$content = fread($file_handle, filesize("/students/students.txt"));
Same thing when you write contents to file using fwrite. Its reference to the file is a File Handle opened using fopen NOT the filepath. when opening a file using fopen() you can also check if the $file_handle returned is a valid resource or is false. If false, it means the fopen operation was not successful.
So your code:
fopen("/students/students.txt", "w");
fwrite("/students/students.txt", $content."\n".$SID);
fclose("/students/students.txt");
Needs to be re-written as:
$file_handle = fopen("/students/students.txt", "w");
fwrite($file_handle, $content."\n".$SID);
fclose($file_handle);
You can see that fclose operates on file handles as well.
File Handle (as per php.net):
A file system pointer resource that is typically created using fopen().
Here are a couple of diagnostic functions that allow you to validate that a file exists and is readable. If it is a permission issue, it gives you the name of the user that needs permission.
function PrintMessage($text, $success = true)
{
print "$text";
if ($success)
print " [<font color=\"green\">Success</font>]<br />\n";
else
print(" [<font color=\"red\">Failure</font>]<br />\n");
}
function CheckReadable($filename)
{
if (realpath($filename) != "")
$filename = realpath($filename);
if (!file_exists($filename))
{
PrintMessage("'$filename' is missing or inaccessible by '" . get_current_user() . "'", false);
return false;
}
elseif (!is_readable($filename))
{
PrintMessage("'$filename' found but is not readable by '" . get_current_user() . "'", false);
return false;
}
else
PrintMessage("'$filename' found and is readable by '" . get_current_user() . "'", true);
return true;
}
I've re-written your code with (IMO) a cleaner and more efficient code:
<?php
$SID = "SOMETHING MYSTERIOUS";
setcookie("Student", $SID, time()+43200, "/");
$file = "/students/students.txt"; //is the full path correct?
$content = file_get_contents($file); //$content now contains /students/students.txt
$size = filesize($file); //do you still need this ?
echo $content;
file_put_contents($file, "\n".$SID, FILE_APPEND); //do you have write permissions ?
file_get_contents
file_get_contents() is the preferred way to read the contents of a
file into a string. It will use memory mapping techniques if supported
by your OS to enhance performance.
file_put_contents
This function is identical to calling fopen(), fwrite() and
fclose() successively to write data to a file. If filename does not
exist, the file is created. Otherwise, the existing file is
overwritten, unless the FILE_APPEND flag is set.
Notes:
Make sure the full path /students/students.txt is
correct.
Check if you've read/write permissions on /students/students.txt
Learn more about linux file/folder permissions or, if you don't access to the shell, how to change file or directory permissions via ftp
Try to do this:
fopen("students/students.txt", "r");
And check to permissions read the file.

PHP Having problems with find and replace in LARGE CSV

I am writing a PHP script so that I can do a find and replace in a large CSV file. I wrote this script:
// FIND AND REPLACE
$sourcePath = 'custom.csv';
$tempPath = $sourcePath . 'temp';
$source = fopen($sourcePath, 'r');
$target = fopen($tempPath, 'w');
while(!feof($source)) {
$line = preg_replace ("village", "village/",fgets($source));
fwrite($target, $line);
}
fclose($source);
fclose($target);
unlink($sourcePath);
rename($tempPath, $sourcePath);
But I am getting these errors,
Warning: feof() expects parameter 1 to be resource, boolean given
Warning: fgets() expects parameter 1 to be resource, boolean given
Warning: preg_replace(): Delimiter must not be alphanumeric or backslash
$source = fopen($sourcePath, 'r'); isn't returning what you think it is.
It's likely returning false, which typically happens when PHP can't find the file at the path you provided. If you're certain the file exists, you should confirm that the user executing the script has the proper permissions to read the file.
You're second issue regarding preg_replace() is being caused by not using delimiters. They are needed in the first argument.
$line = preg_replace ("/village/", "village/",fgets($source));
However, regular expressions aren't needed with this simple of a replacement. You should instead use str_replace() and the script should run faster.
Your code should look like this:
<?php
$sourcePath = 'custom.csv';
$tempPath = $sourcePath . 'temp';
$source = fopen($sourcePath, 'r');
$target = fopen($tempPath, 'w');
if($source){
while(!feof($source)) {
$line = str_replace("Village\\", "Village",fgets($source));
fwrite($target, $line);
}
} else {
echo "$sourcePath not found, or using the wrong permissions.";
}
fclose($source);
fclose($target);
unlink($sourcePath);
rename($tempPath, $sourcePath);
?>
You are not checking if fopen is actually returning a file pointer resource or a false result. It is likely returning false and throwing the warning that a boolean is provided.
Also, you could use:
$line = str_replace("village", "village/", fgets($source));

Copy file from url to my own server remains file to 0mb

I'm facing to a problem and I'm not really sure if this is the right way of doing this. I need to copy a file from a remote server to my server with php.
I use the following script :
public function download($file_source, $file_target) {
$rh = fopen($file_source, 'rb');
$wh = fopen($file_target, 'w+b');
if (!$rh || !$wh) {
return false;
}
while (!feof($rh)) {
if (fwrite($wh, fread($rh, 4096)) === FALSE) {
return false;
}
echo ' ';
flush();
}
fclose($rh);
fclose($wh);
return true;
}
but in the end, the file size remains at 0.
EDIT : I update my question, because there are still some things I didn't understand :
About fread, I used 2048mb. But it didn't work.
I found the script above, which uses 4096mb.
My question : How to determine which quantity of memory (?) to use in order no get the file downloaded anytime ? Because this one works on a specific machine (dedicated), but will it on a shared host, if I cannot modify the php.ini ?
Thanks again
filesize() expects a filename/path. You're passing in a filehandle, which means filesize will FAIL and return a boolean false.
You then use that false as the size argument for your fread, which gets translated to an integer 0. So essentially you're sitting there telling php to read a file, 0 bytes at a time.
You cannot reliably get the size of a remote file anyways, so just have fread some fixed number of bytes, e.g. 2048, at a time.
while(!feof($handle)) {
$contents = fread($handle, 2048);
fwrite($f, $contents);
}
and if that file isn't too big and/or your PHP can handle it:
file_put_contents('local.mp4', file_get_contents('http://whatever/foo.mp4'));

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.

PHP - failed write

I am stuck and in need of a hand. Hope someone can help?
Anyone have any idea why I am getting "failed write" in this code?
$write_file = "/usr/home/public_html/php/users_v2.sql";
$write_handle = fopen($write_file, "w") || die("Couln't open users_v2!");
if (is_writeable($write_file)) {
if ($write_handle === FALSE) echo 'Failed handle?!';
if (fwrite($write_handle, "Hi\n") === FALSE) echo "Failed write!\n";
}
fclose($write_handle);
Thanks in advance.
By using the OR operator when creating your file handle, you are returning a boolean value depending on the operation. So $write_handle will contain true or false, instead of the file resource. A better way to open a file for writing and test that it was successful would be this:
$write_handle = fopen($write_file, 'w');
if ($write_handle === false)
{
die('Could not open file ' . $write_file);
}
Additionally, you could use the file_put_contents() function which handles the fopen(), fwrite() and fclose() for you. I only recommend this if you are executing only one write to the same file, as it will be a lot of overhead, and unless you pass the FILE_APPEND flag, it will empty the file for every write.
I have seen it used everywhere but the problem is the || die("Couln't open users_v2!");
First I added:
error_reporting(E_ALL);
to see what php is reporting for errors.
$write_handle = fopen($write_file, "w") || die("Couln't open users_v2!");
fclose($write_handle);
Returns an invalid stream handle error and file handle of 1. Without it the returned file handle is "Resource id #x".
Changing the line to:
$write_handle = fopen($write_file, "w"); // || die("Couln't open users_v2!");
and your code works fine. Gonna go post this on php.net now.

Categories