I am working on this snippet. Why am I getting fgets() error on line 6?
Warning: fgets() expects parameter 1 to be resource, string given in
D:\wamp64\www\WP\wp-content\plugins\test.php on line 6
Code:
<?php
$file = "http://localhost:8080/WP/Data.csv";
function wdm_validate_csv($csv_file)
{
$requiredHeaders = array('title', 'price','color');
$firstLine = fgets($csv_file); //get first line of the CSV file
$fileHeader = str_getcsv(trim($firstLine), ',', "'"); //parse the contents to an array
//check the headers of the file
if ($foundHeaders !== $requiredHeaders) {
// report an error
return false;
}
return true;
}
wdm_validate_csv($file);
As you can see I have a CSV file at this $file = "http://localhost:8080/WP/Data.csv" directory and trying to read it
if you read a file with Url you can use the function file_get_contents(), but if you need to read in the local server change this http://localhost:8080/WP/Data.csv for "./WP/Data.csv" if the php file is in the root directory.
`
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);
?>
`
Using file()[0] will give you the first line of a file.
file() returns a file as an array line by line, and [0] means give me the first line only.
Then I assume it's a typo $fileheaders and $foundheaders?
$file = "http://localhost:8080/WP/Data.csv";
function wdm_validate_csv($csv_file)
{
$requiredHeaders = array('title', 'price','color');
$firstLine = file($csv_file)[0]; //get first line of the CSV file
$fileHeader = str_getcsv(trim($firstLine), ',', "'"); //parse the contents to an array
//check the headers of the file
if ($fileHeader !== $requiredHeaders) {
// report an error
return false;
}
return true;
}
wdm_validate_csv($file);
Assuming you're going to do other stuff with the file after validating its headers, I think it makes sense to open it and pass the resource handle to the function instead of just the path.
$file = fopen("http://localhost:8080/WP/Data.csv");
$valid_headers = wdm_validate_csv($file);
If your CSV is valid, you can combine fgets and str_getcsv into one operation with fgetcsv.
function wdm_validate_csv($csv_file)
{
$requiredHeaders = array('title', 'price','color');
$fileHeader = fgetcsv($csv_file); //get first line of the CSV file
return $fileHeader == $requiredHeaders;
}
file_get_contents and file are great, but they're both going to read the entire file in, which is a bit heavy if you just need to check the first line.
As the error suggests, fgets requires a resource, not a string. Try using file_get_contents instead:
<?php
$file = "http://localhost:8080/WP/Data.csv";
function wdm_validate_csv($csv_file)
{
$requiredHeaders = array('title', 'price','color');
$firstLine = file_get_contents($csv_file); //get first line of the CSV file
$data = str_getcsv(trim($firstLine), ',', "'"); //parse the contents to an array
$foundHeaders = array_key_exists($data[0]) ? $data[0] : null;
//check the headers of the file
if ($foundHeaders !== $requiredHeaders) {
// report an error
return false;
}
return true;
}
wdm_validate_csv($file);
Related
I want to write a PHP code which write a string line in text file if the line already available in text file then count the requests for example
text file contain:
red.apple:1
big.orange:1
green.banana:1
If some one request to add big.orange in file if its already available in file then count as big.orange:2 if not available then write new line big.orange:1
after execution code text file
red.apple:1
big.orange:2
green.banana:1
I've written the following code but not working.
<?PHP
$name = $_GET['fname']
$file = fopen('request.txt', "r+") or die("Unable to open file!");
if ($file) {
while (!feof($file)) {
$entry_array = explode(":",fgets($file));
if ($entry_array[0] == $name) {
$entry_array[1]==$entry_array[1]+1;
fwrite($file, $entry_array[1]);
}
}
fclose($file);
}
else{
fwrite($file, $name.":1"."\n");
fclose($file);
}
?>
Instead of creating your own format which you need to parse manually, you can simply use json.
Below is a suggestion about how it would work. It will add the requested fname value if it doesn't already exist and will also create the file if it doesn't already exists.
$name = $_GET['fname'] ?? null;
if (is_null($name)) {
// The fname query param is missing so we can't really continue
die('Got no name');
}
$file = 'request.json';
if (is_file($file)) {
// The file exists. Load it's content
$content = file_get_contents($file);
// Convert the contents (stringified json) to an array
$data = json_decode($content, true);
} else {
// The file does not extst. Create an empty array we can use
$data = [];
}
// Get the current value if it exists or start with 0
$currentValue = $data[$name] ?? 0;
// Set the new value
$data[$name] = $currentValue + 1;
// Convert the array to a stringified json object
$content = json_encode($data);
// Save the file
file_put_contents($file, $content);
If you still need to use this format (like, this is some exam test or legacy), try the function:
function touchFile($file, $string) {
if (!file_exists($file)) {
if (is_writable(dirname($file))) {
// create file (later)
$fileData = "";
} else {
throw new ErrorException("File '".$file."' doesn't exist and cannot be created");
}
} else $fileData = file_get_contents($file);
if (preg_match("#^".preg_quote($string).":(\d+)\n#m", $fileData, $args)) {
$fileData = str_replace($args[0], $string.":".(intval($args[1])+1)."\n", $fileData);
} else {
$fileData .= $string.":1\n";
}
if (file_put_contents($file, $fileData)) {
return true;
} else {
return false;
}
}
I am trying to read the contents of a file line by line with Laravel.
However, I can't seem to find anything about it anywhere.
Should I use the fopen function or can I do it with the File::get() function?
I've checked the API but there doesn't seem to have a function to read the contents of the file.
You can use simple PHP:
foreach(file('yourfile.txt') as $line) {
// loop with $line for each line of yourfile.txt
}
You can use the following to get the contents:
$content = File::get($filename);
Which will return a Illuminate\Filesystem\FileNotFoundException if it's not found. If you want to fetch something remote you can use:
$content = File::getRemote($url);
Which will return false if not found.
When you have the file you don't need laravel specific methods for handling the data. Now you need to work with the content in php. If you wan't to read the lines you can do it like #kylek described:
foreach($content as $line) {
//use $line
}
You can use
try
{
$contents = File::get($filename);
}
catch (Illuminate\Contracts\Filesystem\FileNotFoundException $exception)
{
die("The file doesn't exist");
}
you can do something like this:
$file = '/home/albert/myfile.txt';//the path of your file
$conn = Storage::disk('my_disk');//configured in the file filesystems.php
$stream = $conn->readStream($file);
while (($line = fgets($stream, 4096)) !== false) {
//$line is the string var of your line from your file
}
You can use
file_get_contents(base_path('app/Http/Controllers/ProductController.php'), true);
$tmpName = $request->file('csv_file');
$csvAsArray = array_map('str_getcsv', file($tmpName));
This is a second request on the same subject. I wasn't clear
I needed the line to be deleted.
I searched here and found part of a script that is suppose search for
a word and delete the line. There seems to be a slight error with what
I'm trying to do.
I have an option list in a pull down. I would like for it to
remove the line selected. The file choice.php that is called
from the pull down page seems to be released when the php below
is called called because there is no access denied, or violation
errors.
These are the errors I'm getting after adding the 3 last lines I
was told I need.
fopen() expects at least 2 parameters, 1 given
implode(): Invalid arguments passed
fwrite() expects parameter 1 to be resource, boolean given
fclose() expects parameter 1 to be resource, boolean given
Thanks in advance
<?php
// Separate choice.php has the following pull down
// Select item to delete from list
// <option value="item1.php">Item 1</option>
// <option value="item2.php">Item 2</option>
// ...... many items.
$workitem = $_POST["itemtodelete"];
$file = file("option.list.php");
foreach( $file as $key=>$line ) {
if( false !== strpos($line, $workitem) ) {
unset ($file[$key]);
}
}
// Removed "\n"
$file = implode("", $file);
// Told to add this.
$fp = fopen ("option.list.php");
fwrite($fp,implode("",$file);
fclose ($fp);
?>
fopen requires a $mode as the second parameter, so that fails and everything that needs $fp.
Just use file_put_contents. It will even implode the array for you:
$workitem = $_POST["itemtodelete"];
$file = file("option.list.php");
foreach( $file as $key=>$line ) {
if( false !== strpos($line, $workitem) ) {
unset ($file[$key]);
}
}
file_put_contents('option.list.php', $file);
Ok. You are missing some closing parenthesis, as well as other things.
$replaceItem = $_POST['itemtodelete']; // You should filter this data
$newContents = "";
$path = PATH_TO_FILE; // This could be hard coded, but not recommended
$filename = "option.list.php";
// Check to see if the file exists
if ( file_exists($path."/".$filename) ) {
// Wrap our IO stuff so we catch any exceptions
try {
// Open the file for reading
$fp = fopen($path."/".$filename, "r");
if ($fp) {
// Loop line-by-line through the file
while($line = fgets($fp, 4096) !== false) {
// Only add the line if it doesn't contain $replaceItem
// This is case insensitive. I.E. 'item' == 'ITEM'
// For case sensitive, use strstr()
if ( stristr($line, $replaceItem) == false ) {
$newContents .= $line;
}
}
}
// Close our file
fclose($fp);
// Replace the contents of the file with the new contents
file_put_contents($path."/".$filename, $newContents);
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
Edit: Try this. I modified it somewhat.
EDIT after all the answers, i updated the function, and it works
I read out a importfolder. In this folder are many different files available.
Step: I read the folder and add the files to a array
Step: I open every file and try to import
When i cant import a file, then this happens, when another file in this row have to be imported first.
Example: If I open a file "message to a address", this could not be imported, when the address are not added into the database. But in some other file of this filelist is the "create address"-file. When this is created, then it is good, when the "message to a address" will be added to the filelistarray on the end.
My Code give me an offset problem:
function importData( $path, $db, $mail )
{
//Get available Importfiles
$filelist = getFilelist( $path );
for ($i = 0; $i < count($filelist); $i++)
{
$filename = $path . "/" . $filelist[$i];
$file = fopen( $filename,"r" );
while(!feof( $file )) {
$items = explode( ";", fgets( $file ) );
//Get messagetyp
if( strtolower(trim($items[0])) == "nachrichtentyp" )
{
$messagetyp = $items[1];
break;
}
}
fclose($file);
if ( $messagetyp )
{
$f = "import" . $messagetyp;
if( !$f($filename, $db, $mail) )
{
array_push($filelist, $filelist[$i]);
}
}
}
}
This my error, when I push the element to the the filelist-array
PHP Warning: feof() expects parameter 1 to be resource, boolean given in /var/www/symfony/importscript/import.php on line 37
PHP Warning: fgets() expects parameter 1 to be resource, boolean given in /var/www/symfony/importscript/import.php on line 38
According to your errors, problem lies not in array_push but in fopen():
$file = fopen( $filename,"r" );
If php fails to open that file, variable $file will be set to false and because of that feof() and fgets() will give you errors.
You definitely should check if fopen returns another value than FALSE, maybe one of the files does not exist or you are restricted.
I'm trying to define an array with a list of file urls, and then have each file parsed and if a predefined string is found, for that string to be replaced. For some reason what I have isn't working, I'm not sure what's incorrect:
<?php
$htF = array('/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension', '/home/folder/file.extension');
function update() {
global $htF;
$handle = fopen($htF, "r");
if ($handle) {
$previous_line = $content = '';
while (!feof($handle)) {
$current_line = fgets($handle);
if(stripos($previous_line,'PREDEFINED SENTENCE') !== FALSE)
{
$output = shell_exec('URL.COM');
if(preg_match('#([0-9]{1,3}\.){3}[0-9]{1,3}#',$output,$matches))
{
$content .= 'PREDEFINED SENTENCE '.$matches[0]."\n";
}
}else{
$content .= $current_line;
}
$previous_line = $current_line;
}
fclose($handle);
$tempFile = tempnam('/tmp','allow_');
$fp = fopen($tempFile, 'w');
fwrite($fp, $content);
fclose($fp);
rename($tempFile,$htF);
chown($htF,'admin');
chmod($htF,'0644');
}
}
array_walk($htF, 'update');
?>
Any help would be massively appreciated!
Do you have permissions to open the file?
Do you have permissions to write to /tmp ?
Do you have permissions to write to the destination file or folder?
Do you have permissions to chown?
Have you checked your regex? Try something like http://regexpal.com/ to see if it's valid.
Try adding error messages or throw Exceptions for all of the fail conditions for these.
there's this line:
if(stripos($previous_line,'PREDEFINED SENTENCE') !== FALSE)
and I think you just want a != in there. Yes?
You're using $htF within the update function as global, which means you're trying to fopen() an array.
$fh = fopen($htF, 'r');
is going to get parsed as
$fh = fopen('Array', 'r');
and return false, unless you happen to have a file named 'Array'.
You've also not specified any parameters for your function, so array_walk cannot pass in the array element it's dealing with at the time.