how to open a file while inside a foreach(glob....PHP - php

I have a small number of image files and text files. They have the same file name with different extensions. I need to read the image files and for each image I need to read some (tool top) text from the corresponding text file. The problem is the file open inside the "foreach( glob("inserts/*.png")" loop fails. I have output the filename and the fopen works fine. I thought it may be you are unable to open two file concurrently in PHP but I could find nothing about it when I googled
foreach( glob("inserts/*.png" ) as $filename ) {
$path="public/xml/iweb/".$filename;
$insertpath=substr($filename, 0, -3)."txt";
$myfile = fopen($insertpath, "r");
$rec=fread($myfile,filesize($insertpath));
fclose($myfile);
$name=getInnerSubstring($rec,"-");
$HTML5.="<img class='insertimage' src='".$path."' title='".$name."' onclick='insertcomponent(\"".$insertpath."\")'>";
}
One day I hope I know enough to answer questions instead of just asking them. :(

There's no reason why you shouldn't be able to open multiple files and no reason the foreach should break anything that works. My hunch is that the path you're trying to open is wrong. I suggest either debugging the code to see the variables or add an echo to see their content. You should also check if fopen() and fread() don't return some false because they failed. Good luck :)

Related

Overwrite file on server (PHP)

I am making an Android application that need to be able to push files onto a server.
For this I'm using POST and fopen/fwrite but this method only appends to the file and using unlink before writing to the file has no effect. (file_put_contents has the exact same effect)
This is what I have so far
<?php
$fileContent = $_POST['filecontent'];
$relativePath = "/DatabaseFiles/SavedToDoLists/".$_POST['filename'];
$savePath = $_SERVER["DOCUMENT_ROOT"].$relativePath;
unlink($savePath);
$file = fopen($savePath,"w");
fwrite($file,$fileContent);
fclose($file);
?>
The file will correctly delete its self when I don't try and write to it after but if I do try and write to it, it will appended.
Anyone got any suggestions on overwriting the file contents?
Thanks, Luke.
Use wa+ for opening and truncating:
$file = fopen($savePath,"wa+");
fopen
w+: Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
a+: Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
file_put_contents($savePath,$fileContent);
Will overwrite the file or create if not already exist.
read this it will help show all the options for fopen
http://www.php.net/manual/en/function.fopen.php
Found the error, i forgot to reset a string inside of my application

file_put_contents stopped working

I have a PHP code that connects to a FTP server, reads a file's content, makes a minor change, and than overrides the original file.
it looks like:
$stream_context = stream_context_create(array('ftp' => array('overwrite' => true)));
$file_content = file_get_contents($ftp_file); // this line works
$file_content = str_replace('some content', 'another content', $file_content); // this also..
file_put_contents($ftp_file, $file_content, 0, $stream_context); // this one doesn't :/
the real issue is that the "file_put_contents" worked for a long time, but now it doesn't.
what it does now is weird: it deletes the original file from the server..
also, if i'm changing it to something like:
file_put_contents($new_ftp_file, $file_content);
from what I know, it should create the new file and put the content in it, but it doesn't create it at all.
the hosting service i'm using has a PHP version change a few days ago. I don't remember the what the previous version was, but the current is: 5.2.17
thanks! :)
some changes
I found this piece: http://www.php.net/manual/en/function.file-put-contents.php#86864
doting the same as "file_put_contents" but with foen, fwrite and fclose (I send his example because of the results..). his functions is returning "false" if it couldn't to "fopen" the file, or the "bytes" if it succeeded. I got "false" :/
which means it couldn't even do the:
#fopen($filename, 'w');
although the "file_get_contents" with the same file address is working.
reading is working (but if you take the $filename and use it yourself on a client FTP - it works):
#fopen($filename, 'r');
the "open base_dir" for my hosting (which makes the action) is set to false, but the target hosting (which has the target-file) is set to be true.
I had an idea to save the new content on a new file, so I tried something like:
$f = #fopen($new_ftp_file, 'w'); //this one seems to work and connect
fwrite($f, $file_content); // this one seems to work either and returning the number of byes..
fclose($f);
the problem is that none of them really works. I logged in to the FTP address, using the same credentials that my script is using, and I haven't found the new file. It wasn't created at all. (as I remind you, "$new_ftp_file" is a path to a file that doesn't exists, so "w" mode on "fopen" should create it).
file_put_contents do erase the file by default if it already exists. You have to ask him to don't.
Look at here:
http://www.php.net/manual/en/function.file-put-contents.php
See: If filename does not exist, the file is created. Otherwise, the existing file is overwritten, unless the FILE_APPEND flag is set.
this is not the best solution (definitely), but I managed to figure something..
I used 2 different hosts on them same hosting service, both of the having "open base_dir = On" & "safe mode = Off".
it looks something like:
$ftpstring = "ftp://user:password#anotherhosteddomain.com";
$file = file_get_contents($ftpstring . 'index.html'); // this line works as expected. (yeah, the other hosting has this file);
and then, if you're trying to write something like:
$handler = fopen($ftpstring.'index.html', "w");
it wouldn't work, and tell you it cannot access on writing mode to an existing file.
so if you're doing something like:
$newfile_handler = fopen($ftpstring.'index_new_version.html', "w");
fwrite($newfile, "1122");
so yeah - it works!
but now is a tricky issue.. when i'm adding this line:
fclose($newfile_handler);
the new file is deleted from the hosting!!
I couldn't find any reason why "fclose" is deleting the file after it was create at "fopen" and written in at "fwrite".
so if you're not adding the "fclose" line - it works, but it doesn't close the connection, and also I have to actually delete the existing file before I can override it with a new content, which makes it silly..
although it works, I would really like someone to give me a better solution than mine.

PHP - Chunked file copy (via FTP) has missing bytes?

So, I'm writing a chunked file transfer script that is intended to copy files--small and large--to a remote server. It almost works fantastically (and did with a 26 byte file I tested, haha) but when I start to do larger files, I notice it isn't quite working. For example, I uploaded a 96,489,231 byte file, but the final file was 95,504,152 bytes. I tested it with a 928,670,754 byte file, and the copied file only had 927,902,792 bytes.
Has anyone else ever experienced this? I'm guessing feof() may be doing something wonky, but I have no idea how to replace it, or test that. I commented the code, for your convenience. :)
<?php
// FTP credentials
$server = CENSORED;
$username = CENSORED;
$password = CENSORED;
// Destination file (where the copied file should go)
$destination = "ftp://$username:$password#$server/ftp/final.mp4";
// The file on my server that we're copying (in chunks) to $destination.
$read = 'grr.mp4';
// If the file we're trying to copy exists...
if (file_exists($read))
{
// Set a chunk size
$chunk_size = 4194304;
// For reading through the file we want to copy to the FTP server.
$read_handle = fopen($read, 'rb');
// For appending to the destination file.
$destination_handle = fopen($destination, 'ab');
echo '<span style="font-size:20px;">';
echo 'Uploading.....';
// Loop through $read until we reach the end of the file.
while (!feof($read_handle))
{
// So Rackspace doesn't think nothing's happening.
echo PHP_EOL;
flush();
// Read a chunk of the file we're copying.
$chunk = fread($read_handle, $chunk_size);
// Write the chunk to the destination file.
fwrite($destination_handle, $chunk);
sleep(1);
}
echo 'Done!';
echo '</span>';
}
fclose($read_handle);
fclose($destination_handle);
?>
EDIT
I (may have) confirmed that the script is dying at the end somehow, and not corrupting the files. I created a simple file with each line corresponding to the line number, up to 10000, then ran my script. It stopped at line 6253. However, the script is still returning "Done!" at the end, so I can't imagine it's a timeout issue. Strange!
EDIT 2
I have confirmed that the problem exists somewhere in fwrite(). By echoing $chunk inside the loop, the complete file is returned without fail. However, the written file still does not match.
EDIT 3
It appears to work if I add sleep(1) immediately after the fwrite(). However, that makes the script take a million years to run. Is it possible that PHP's append has some inherent flaw?
EDIT 4
Alright, further isolated the problem to being an FTP problem, somehow. When I run this file copy locally, it works fine. However, when I use the file transfer protocol (line 9) the bytes are missing. This is occurring despite the binary flags the two cases of fopen(). What could possibly be causing this?
EDIT 5
I found a fix. The modified code is above--I'll post an answer on my own as soon as I'm able.
I found a fix, though I'm not sure exactly why it works. Simply sleeping after writing each chunk fixes the problem. I upped the chunk size quite a bit to speed things up. Though this is an arguably bad solution, it should work for my uses. Thanks anyway, guys!

How can I include custom text inside a file saved from a php form?

I'm using this code below that simply takes the name of an artist submitted through a form and saves it as a html file on the server.
<?php
if (isset($_GET['artist'])) {
$fileName = $_GET['artist'].".html";
$fileHandler = fopen($fileName, 'w') or die("can't create file");
fclose($fileHandler);
}
?>
What I'm trying to work out is how I could possibly add any code within the file before it is saved. That way every time a user adds an artist I can include my template code within the file. Any help would be great :)
Use fwrite.
Two things:
file_put_contents as a whole will be faster.
Your design is a very bad idea. They can inject a file anywhere on your filesystem, e.g. artist=../../../../etc/passwd%00 would try to write to /etc/passwd (%00 is a NUL byte, which causes fopen to terminate the string in C - unless that's been fixed).
fwrite() allows you to write text to the file.
if (isset($_GET['artist'])) {
$fileName = $_GET['artist'].".html";
$fileHandler = fopen($fileName, 'w') or die("can't create file");
fwrite($fileHandler, 'your content goes here');
fclose($fileHandler);
}
Warning - be very careful about what you write to the filesystem. In your example there is nothing stopping someone from writing to parts of the filesystem that you would never have expected (eg. artist='../index'!).
I sincerely recommend that you think twice about this, and either save content to a database (using appropriate best practices, ie http://php.net/manual/en/security.database.sql-injection.php) or at least make sure that you limit the characters used in the filename strings (eg. only allow characters A-Z or a-z and '_', for example). It's dangerous and exploitable otherwise, and at the very least you run the risk of your site being defaced or abused.
As others have said - you should be able to write php code to the filesystem with fwrite.

What's wrong with my PHP unserialize?

I have a file with the contents:
a:12:{s:12:"a2.twimg.com";i:1308768611;s:12:"a1.twimg.com";i:1308768611;s:12:"a0.twimg.com";i:1308768612;s:12:"a3.twimg.com";i:1308768612;s:8:"this.com";i:1308768613;s:15:"f.prototype.com";i:1308768613;s:15:"c.prototype.com";i:1308768614;s:15:"a.prototype.com";i:1308768614;s:5:"w.com";i:1308768615;s:5:"s.com";i:1308768615;s:5:"f.com";i:1308768615;s:5:"h.com";i:1308768615;}
(It's an array of domains listed on twitter.com as keys and a timestamp as values)
If I call:
unserialize(fread($recentfile, filesize("./neptune_output/recent")))
("./neptune_output/recent" is the location of the $recentfile)
It fails, but if I call unserialize with that string pasted in, it works.
I use the following code to open the file.
$recentfile = fopen("./neptune_output/recent", 'a+')
I've tried putting the fopen mode as 'c+' and 'a+b' but it won't work.
Do I need to post more code?
Why don't you just read it with file_get_contents() rather than messing about with opening it and working out the file size?
a+ means: "Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it."
If you just want to read "r" is enough:
$recentfile = fopen("./neptune_output/recent", 'r')
See http://nl2.php.net/manual/en/function.fopen.php

Categories