I have a script checking if a file exists:
function fileExists($url) {
$fh = fopen($url, 'r');
if (is_resource($fh)) {
fclose($fh);
return true;
}
return false;
}
Everything went right until I tried to uploaded files whose name contains white space. Call $url the file's url, when I put it in the browser, it displays correctly the file, but is_resource($fh) always returns false. Someone could help ?
Before $fh = fopen($url, 'r'); add this:
$parts = pathinfo($url);
$url = $parts['dirname'].'/'.rawurlencode($parts['basename']);
Btw, there is a PHP bug...
Related
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
}
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);
}
}
I have a little problem with this code I have here. This code searches in a txt file and returnes what it has found.
Now what I want to do is change the file path with a $_GET method
But when I put in a $_GET method inside the "" it just says alot of errors such as "Your path cannot be empty"
What does not work:
$handle = #fopen(."$_GET['filepath']"., "r");
How I want it
$handle = #fopen("I/want/this/$_get/method", "r");
Full code
<?php
function find_value($input) {
// $input is the word being supplied by the user
$handle = #fopen("/users/edwin/list.txt", "r");
if ($handle) {
while (!feof($handle)) {
$entry_array = explode(":",fgets($handle));
if ($entry_array[0] == $input) {
return $entry_array[1];
}
}
fclose($handle);
}
return NULL;
}
?>
Thanks :)
Check the way you're handling your quotes.
$handle = #fopen($_GET['filepath'], "r");
Since it's a variable, it does not have to be encapsulated at all, unlike a string.
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.
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.