fwrite if string doesn't exist in file - php

I am currently working an auto-content-generator script's sitemap. I got to know that google accept sitemap in simple text file that contains one URL per line.
so I created a file named 1.txt and wrote a script to add current page URL to 1.txt when a user visits.
test.php is:
$file = 'assets/sitemap/1.txt';
$url = "http://".$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI]."\n";
$file = fopen($file, 'a');
fwrite($file, $url);
fclose( $file );
This script writes the page URLto 1.txt every time someone hits the page. But the problem is, it creates too much duplicate links. So I want to add a filter to not add a string (URL in this case) if it already exists.
After surfing a while, I got a solution here (second snippet) that is resource friendly: PHP check if file contains a string
I made the following modification but it is not working (not adding anything at all):
$file = 'assets/sitemap/1.txt';
$url = "http://".$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI]."\n";
if(exec('grep '.escapeshellarg($url).' assets/sitemap/1.txt')) {}
else{
$file = fopen($file, 'a');
fwrite($file, $url);
fclose( $file );
}

This is hopefully easier to understand:
$file = 'assets/sitemap/1.txt';
$url = "http://".$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI]."\n";
$text = file_get_contents($file);
if(strpos($text, $url) === false) {
file_put_contents($file, $url, FILE_APPEND);
}
Read the file contents into a string $text using file_get_contents()
Check if $url is in the string $text using strpos()
If $url is not in the string $text, append the $url to the file using file_put_contents()
To count the total lines, you can start using file() to load the file lines into an array. Then check if the $url is in the array using in_array():
$lines = file($file);
$count = count($lines); // count the lines
if(!in_array($url, $text)) {
file_put_contents($file, $url, FILE_APPEND);
$count++; // if added, add 1 to count
}

Related

How can I remove unwanted spaces from txt file

I'm trying to modify my txt file what I'm using in dokuwiki.
I generate timestamp on top of the txt file like this:
function filecont($file,$data)
{
$fileContents = file($file);
array_shift($fileContents);
array_unshift($fileContents, $data);
$newContent = implode("\n", $fileContents);
$fp = fopen($file, "w+");
fputs($fp, $newContent);
fclose($fp);
}
And my original txt file looks like this:
Now when I use my function:
$txt= "Last generated: " . date("Y M D h:i:s");
filecont($file,$txt);
I get a result like this:
Now I don't want to remove my ====== Open IoT book ======, it's probably because I don't have empty space in the first line?
But the worst problem that I have Is that is generates many empty spaces what I don't want.
I only want to get last generated at the top of the txt file and anything else untouched
I tested your code and removed the extra newlines by changing the line:
$fileContents = file($file);
to
$fileContents = file($file, FILE_IGNORE_NEW_LINES);
Adding the FILE_IGNORE_NEW_LINES flag stops a newline being added to each element/line.
http://php.net/manual/en/function.file.php.
I also removed the array_unshift(), which leaves '====== Open IoT book ======' in the file.
So my final function looked like this:
function filecont($file,$data)
{
$fileContents = file($file, FILE_IGNORE_NEW_LINES);
//array_shift($fileContents); Removed to preserve '====== Open IoT book ======' line.
array_unshift($fileContents, $data);
$newContent = implode("\n", $fileContents);
$fp = fopen($file, "w+");
fclose($fp);
}
Might just delete this line
array_shift($fileContents);
solve your problem?
when you get elements of file you need to check whether Last generated: is as your first row or not accordong to it yu need to use array_shift
$fileContents = file($file);
if(stripos($fileContents[0],"Last generated:") !== false)
{
array_shift($fileContents); //if found use shift
}
array_unshift($fileContents, $data);

Batch download URLs in PHP?

So, I have a PHP script that is supposed to download images that the user inputs. However, if the user uploads a TXT file and it contains direct links to images, it should download the images from all the URLs in the file. My script seems to be working, although it seems that only the last file is downloaded while the others are stored as files containing no data.
Here's the portion of my script where it parses the TXT
$contents = file($file_tmp);
$parts = new SplFileObject($file_tmp);
foreach($parts as $line) {
$url = $line;
$dir = "{$save_loc}".basename($url);
$fp = fopen ($destination, 'w+');
$raw = file_get_contents($url);
file_put_contents($dir, $raw);
}
How do I make it download every URL from the TXT file?
When you iterate over an SplFileObject, you get the whole line, including whitespace. Your URL will thus be something like
http://example.com/_
(php seems to mangle the newline to an underscore) and thus you'll get an error for many URLs (some URLs will still work fine, since they contain the important information prior. For instance, Batch download URLs in PHP? works, but https://stackoverflow.com/_ does not). If an error occurs, file_get_contents will return false, and file_put_contents will interpret that like an empty string.
Also, the line $fp = fopen ($destination, 'w+'); is really strange. For one, since $destination is not defined, it would error anyways. Even if $destination is defined, you'll end up with lots of file handles and overwrite that poor file multiple times. You can just remove it.
To summarize, your code should look like
<?php
$file_tmp = "urls.txt";
$save_loc = "sav/";
$parts = new SplFileObject($file_tmp);
foreach($parts as $line) {
$url = trim($line);
if (!$url) {
continue;
}
$dir = "{$save_loc}".basename($url);
$raw = file_get_contents($url);
if ($raw === false) {
echo 'failed to donwload ' . $url . "\n";
continue;
}
file_put_contents($dir, $raw);
}
It looks like line
$parts = new SplFileObject($file_tmp);
isn't necessary as well as
$fp = fopen ($destination, 'w+');
file() function reads entire file into array. You just have call trim() on each array element to remove new line from characters. Following code should work properly:
<?php
$save_loc = './';
$urls = file('input.txt');
foreach($urls as $url) {
$url = trim($url);
$destination = $save_loc . basename($url);
$content = file_get_contents($url);
if ($content) {
file_put_contents($destination, $content);
}
}

PHP - Search for an URL patterns in a CSV file and replace it

I have a csv file with multiple columns, in some of these columns there are some HTML tags that looks like StreamHandler.ashx?SubscriptionID=6348. Then there is a folder that contains all images renamed with ID.Extension i.e. 6348.jpg.
I would like to create a script that searches for StreamHandler.ashx?SubscriptionID=6348 and replaces it with http://newdomain.com/images/6348.jpg.
Note that not all the files are .jpg so the extension needs to be checked when the file is found.
$file = fopen("images.csv", "r");
$lines = array();
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
$lines[] = $line;
}
foreach ($lines as $line => $data) {
$data = preg_replace_callback('/StreamHandler\.ashx\?SubscriptionID=([0-9]+)/', function($matches) {
$img = $matches[1]; //get the filename
$img = glob("/Users/sandro/Sites/test/destination/" . $img . ".*"); //find the file in the fileserver (in the current directory)
$img[0] = str_replace ( "/Users/sandro/Sites/test/destination/", 'http://newdomain.com/images/', $img[0] );
if( isset($img[0]) ) { //was there a match?
return $img[0]; //replace
}
return $matches[0]; //dont replace because file doesnt exist
}, $data);
print_r($data);
}
fclose($file);
I've written the part to open and read the csv file but the search is still missing. Any thoughts?
Thanks
You can do a preg_replace_callback to find the string you want to search, then look the file extension up, and replace.
Find matches to replace
See if the file exists by looking for the filename
If it exists, replace string
If it doesn't exist, keep current string
$csv = preg_replace_callback('/StreamHandler\.ashx\?SubscriptionID=([0-9]+)/', function($matches) {
$file = $matches[1]; //get the filename
$file = glob($file .".*"); //find the file in the fileserver (in the current directory)
if( isset($file[0]) ) { //was there a match?
return 'http://newdomain.com/images/'. $file[0]; //replace
}
return $matches[0]; //dont replace because file doesnt exist
}, $csv);
Example
I have the file 6348.png.
My csv file holds: StreamHandler.ashx?SubscriptionID=6348,StreamHandler.ashx?SubscriptionID=6349,StreamHandler.ashx?SubscriptionID=635,StreamHandler.ashx?SubscriptionID=64
The output:
http://newdomain.com/images/6348.png,StreamHandler.ashx?SubscriptionID=6349,StreamHandler.ashx?SubscriptionID=635,StreamHandler.ashx?SubscriptionID=64

PHP fgets() won't work unless it's implemented with a variable?

I'm writing some code that can read in from a .txt file a display it on a webpage.
I had problems in my initial code, in that it would read in any text and it would erase whatever was in the document.
My original code:
function readIn(){
$input = fopen("input.txt", "r"); //Open the file, save opened file in input
$line = fgets($input);
fclose($input);
return $line
}
It only started working once I put in a While loop to go through EVERY LINE
function readIn(){
$input = fopen("input.txt", "r"); //Open the file, save opened file in input
$fullText = ""; //Variable full text
while(!feof($input)){
$line = fgets($input);
$fullText = $fullText . $line;
}
fclose($input);
return $fullText;
}
echo readIn();
Use "file_get_contents" to read an entire file into a variable, and then output in whatever fashion you choose.

write the out put on file

I am very new to php, and i have search and put together this script to convert text to csv and write the out put on the file.
$File = "/var/apache2/htdocs/loginS/host.txt";
$Handle = fopen($File,"r");
$Content = fread ($Handle,filesize ($File));
fclose($File);
fclose($Handle);
$Content = explode("\t", $Content);
foreach($Content as $Value) {
//echo $Value."|"; // till this line working
fwrite($save, $Value);
fclose($save);
}
the problem is when I try to write on the file. I got only one line.what is my error.
You are calling fclose() on the file in your loop that is writing records. fclose() closes the file handle so it is no longer valid and cannot be written to.
Move fclose($save); after the } that ends the foreach() with your content.
Also, you could simplify things a bit by calling $Content = file_get_contents($File); since that is what you are doing in effect with fread(). Also, since $File is just a string variable, calling fclose() on it is unnecessary and doesn't do anything. You were correctly closing it by calling fclose() on $Handle. But using file_get_contents() will eliminate the need for both. The only file you would need is the one you were writing to.
Here is an example using the file() function which reads each line of a file into an array.
$file = '/var/apache2/htdocs/loginS/host.txt';
$content = file($file);
$save = fopen('./out.csv', 'w+');
foreach($content as $line) {
$line = rtrim($line, "\r\n"); // remove the newline from $line
$parts = explode("\t", $line);
$lineCsv = implode('|', $parts); // or ',' ?
fwrite($save, $lineCsv . "\n"); // write output to file
}
fclose($save);

Categories