php fopen - name of file - php

I currently have:
<?php
if (isset($_POST["submitwrite"])) {
$handle = fopen("writetest.txt","w+");
if ($handle) {
fwrite($handle, "Dan"."¬".$_POST["username"]."¬".$_POST["pollname"]."¬".$_POST["ans1"]."¬".$_POST["ans2"]."¬".$_POST["ans3"]."¬".time());
fclose($handle);
}
}
?>
However I need to adjust the filename to be dynamic, instead of 'writetest.txt' I would like it to be: username+pollname+time.txt taking the $_post variables.
I would also like to change the directory these files are stored in to /results.
Help please...

You mean doing something like this?
$filename = '/results/' . $_POST['username'] . '/' . $_POST['pollname'] . '/time.txt';
if (isset($_POST["submitwrite"])) {
$handle = fopen($filename,"w+");
// etc...
Or am I not understanding you?
Edit
To address the issue BalusC pointed out, this is a more complete solution.
It makes sure the $_POST['username'] and $_POST['pollname'] values are valid, so they won't create an invalid or possibly harmful $filename.
<?php
$basedir = '/results';
$basename = 'time.txt';
// Get user and poll names
$username = $_POST['username'];
$pollname = $_POST['pollname'];
// Counteract the old magic_qutoes feature, if needed.
if(get_magic_quotes_gpc()) {
$username = stripslashes($username);
$pollname = stripslashes($pollname);
}
// Validate user and poll names.
$regexp = '/^[\w\d\_\-\. \']+$/iu';
if(!preg_match($regexp, $username) || !preg_match($regexp, $pollname)) {
echo 'Username or pollname is invalid. Aborting!';
}
else {
// Compile the complete file name
$filename = $basedir . '/' . $username . '/' . $pollname . '/' . $basename;
// Write to the file
if (isset($_POST["submitwrite"])) {
$handle = fopen($filename,"w+");
if ($handle) {
fwrite($handle, "Dan"."¬".$_POST["username"]."¬".$_POST["pollname"]."¬".$_POST["ans1"]."¬".$_POST["ans2"]."¬".$_POST["ans3"]."¬".time());
fclose($handle);
}
}
}
?>

fopen creates (at least tries) the file if it does not exist, so
$filename = $username . $pollname . $time . '.txt';
$handle = fopen($filename, 'w+');
will work fine.
By the way, w+ places the pointer at the beginning of the file. If the file already has some data, it will truncate it first. If you want to append data to the file, you may want to use 'a+'

Related

Having an issue with the fopen() php function

I have a users directory and a child directory for the login/register system. I have a file, testing.php, to try to figure out how to create a directory in the users directory AND create a PHP file within that same directory. Here's my code:
<?php
$directoryname = "SomeDirectory";
$directory = "../" . $directoryname;
mkdir($directory);
$file = "../" . "ActivationFile";
fopen("$file", "w");
?>
I'm able to get mdkir($directory) to work, but not the fopen("$file", "w").
Try this, this should normally solve your problem.
PHP delivers some functions to manipulate folder & path, it's recommended to use them.
For example to get the current parent folder, you can use dirname function.
$directoryname = dirname(dirname(__FILE__)) . "/SomeDirectory";
if (!is_dir($directoryname)) {
mkdir($directoryname);
}
$file = "ActivationFile";
$handle = fopen($directoryname . '/' . $file, "w");
fputs($handle, 'Your data');
fclose($handle);
This line is equivalent to "../SomeDirectory"
dirname(dirname(__FILE__)) . "/SomeDirectory";
So when you open the file, you open "../SomeDirectory/ActivationFile"
fopen($directoryname . '/' . $file, "w");
You can use the function touch() in order to create a file:
If the file does not exist, it will be created.
You also forgot to re-use $directory when specifying the filepath, so the file was not created in the new directory.
As reported by Fred -ii- in a comment, error reporting should also be enabled. Here is the code with these changes:
<?php
// Enable error output, source: http://php.net/manual/en/function.error-reporting.php#85096
error_reporting(E_ALL);
ini_set("display_errors", 1);
$directoryname = "SomeDirectory";
$directory = "../" . $directoryname;
mkdir($directory);
$file = $directory . "/ActivationFile";
touch($file);
try this:
$dirname = $_POST["DirectoryName"];
$filename = "/folder/{$dirname}/";
if (file_exists($filename)) {
echo "The directory {$dirname} exists";
} else {
mkdir("folder/{$dirname}", 0777);
echo "The directory {$dirname} was successfully created.";
}

Losing variable value when trying to copy file using mailReader.php

I'm using the mailReader script found here: https://github.com/stuporglue/mailreader
I am trying to copy the file(s) after upload to another folder.
The file(s) upload correctly to the folder where the script resides.
When I try to run a copy command, the filename variable is empty.
Here is the portion of the code I am working with: The last three lines are what I added.
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I receive confirmation by email that the file(s) are uploaded, then another email with the error message.
Warning: copy(/attachments/W7652222-546/1453406138_residential-print_from_td.pdf): failed to open stream: No such file or directory in /home/myhost/public_html/mailreader/mailReader.php on line 224
224 being the line number of my added code.
The source filename is missing from in front of /attachments...
Anyone have any thoughts?
$name is defined in the while loop and may not be accessible on the upper scopes my suggestion is to change your code to this:
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
$name = '';
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I hope this solves your problem
I ended up defining a constant of email_id in the private function saveToDb, then running a script after everything else is finished to query the table using the email_id and looping through the records moving the files.

PHP fopen() won't write to txt files in some cases

I'm not sure if it has to do with my permissions for file writing, or if I'm just plain doing it wrong.
Here is my PHP code:
Note: this is located in www.sitename/folder1/folder2/index.php
$user = $_POST['user'];
$pass = $_POST['pass'];
$fp = fopen("../folder1/test.txt", "a");
$savestring = $user . "\n" . $pass . "\n";
fwrite($fp, $savestring);
fclose($fp);
It doesn't work. It says it is unwritable.
I tried this too: /folder1/test.txt
and http://sitename.com/folder1/test.txt
The only thing that works is fopen("folder1/test.txt"a");, but that writes to www.sitename.com/folder1/folder2/folder1/test.txt, which is what I completely do not want.
Is it something I did wrong?

PHP fwrite() how to insert a new line after some specific line

I'm new here.
Anyway, I did my research on fwrite(), but I couldn't find solution, so i'm asking for help.
What I want is f.e. to add a new line of text after some other specific line.
F.e. I have a .txt file in which there is:
//Users
//Other stuff
//Other stuff2
Now what I'd like to do is be able to add a new user below //Users without touching "Other Stuff" and "Other Stuff 2". So it should look something like this:
//Users
Aneszej
Test321
Test123
//Other stuff
//Other stuff2
What I have so far:
$config = 'test.txt';
$file=fopen($config,"r+") or exit("Unable to open file!");
$date = date("F j, Y");
$time = date("H:i:s");
$username = "user";
$password = "pass";
$email = "email";
$newuser = $username . " " . $password . " " . $email . " " . $date . " " . $time;
while (!feof($file)) {
$line=fgets($file);
if (strpos($line, '//Users')!==false) {
$newline = PHP_EOL . $newuser;
}
}
fwrite($file, $newline);
fclose($file);
test.txt file
//Users
//Something Else
//Something Else 2
But this only writes users to the end of the .txt file.
Thanks a lot everyone for your help! It's solved.
I modified your code, I think follows is what you need, and I also put comment, function below will keep adding new user, you can add condition that to check user exist.
$config = 'test.txt';
$file=fopen($config,"r+") or exit("Unable to open file!");
$date = date("F j, Y");
$time = date("H:i:s");
$username = "user";
$password = "pass";
$email = "email";
$newuser = $username . " " . $password . " " . $email . " " . $date . " " . $time."\r\n"; // I added new line after new user
$insertPos=0; // variable for saving //Users position
while (!feof($file)) {
$line=fgets($file);
if (strpos($line, '//Users')!==false) {
$insertPos=ftell($file); // ftell will tell the position where the pointer moved, here is the new line after //Users.
$newline = $newuser;
} else {
$newline.=$line; // append existing data with new data of user
}
}
fseek($file,$insertPos); // move pointer to the file position where we saved above
fwrite($file, $newline);
fclose($file);
You write the new content at the end of the reading, so it has to write at the end of file - the cursor is there after reading all the lines.
Either you store all the content in php-variable and overwrite the file in the end, or you rewind the curser with fseek as mentioned by Robert Rozas comment. That should be done as soon as you read the "Something else" - line.
Try fseek:
<?php
$file = fopen($filename, "c");
fseek($file, -3, SEEK_END);
fwrite($file, "whatever you want to write");
fclose($file);
?>
PHP Doc: http://php.net/manual/en/function.fseek.php
You need to break after you find '//Users'. You keep reading to the end of the file.

Check if file exist before renaming file upon upload

I need help with adding the feature to check whether a file exists when uploading.
This is how the upload.php code looks like for uploading:
$file_name = $HTTP_POST_FILES['ljudfil']['name'];
$random_digit=rand(0000,9999);
$mp3 ='.mp3';
$pdf ='.pdf';
$datum = date('Ymd');
$new_file_name=$random_digit.$file_name;
$target_path1 = $target_path . $orgnr . '_' . $gsm . $pdf;
$target_path3 = $target_path . 'AC' . $datum . $new_file_name . $mp3;
$target_path11 = $target_path4 . $orgnr . '_' . $gsm . $pdf;
$target_path33 = $target_path4 . 'AC' . $datum . $new_file_name . $mp3;
$targetljudfilftp = 'AC' . $datum . $new_file_name . $mp3;
move_uploaded_file($_FILES['avtalsfil1']['tmp_name'], $target_path1);
move_uploaded_file($_FILES["ljudfil"]["tmp_name"], $target_path3);
$sql = "INSERT INTO affarer (tid, cid, orgnr, ljudfilftp) VALUES
(CURDATE(),'$date','$cid','$orgnr', '$targetljudfilftp')";
As you can see, it renames the uploaded file including a random number.
Sometimes, it happens that it renames the file to a number that already exists.
When that happens, it overwrites the previous file on my server.
So, how can I add a function to check whether the target name exists before it is used for renaming?
You can use
if (file_exists($target_path1))
to verify whether a file exists.
You would do better, though, to change strategy and employ tempnam:
$target_path = tempnam ($target_path, 'AC' . $datum . $file_name . $mp3)
This will create a file such as "AC_2012_Anacreon.mp3_xTfKxy" but you have the guarantee of it being unique, while even using file_exists would expose you to the risk of a concurrency collision.
Of course the file no longer has a .mp3 extension, so you have to take it into account when you scan the directory and supply files for download.
A still not secure, but maybe easier way is this:
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
touch($newname);
if (!filesize($newname))
break;
}
or you can use a lock file to guarantee no concurrency (and therefore, that file_exists will return the truth and it will stay the truth):
$fp = fopen('.flock', 'r+');
if (flock($fp, LOCK_EX))
{
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
{
// this creates the file uniquely for us.
// all other writers will find the file already there
touch($newname);
}
}
flock($fp, LOCK_UN);
}
else
die("Locking error");
fclose($fp);
// $newname is now useable.
Use the file_exists builtin function.
You could change the way your random digists are created by using (for example) a time based method
$random_digit = microtime(TRUE);
You can use as below
$random_digit = time();
Instead off using 'rand' function which can generate a duplicated number, you can use 'uniqid'php function, it returns a unique id ( http://www.php.net/manual/en/function.uniqid.php ).
If you still want to use the 'rand' you can use 'file_exists' function with the generated file name as param ( http://www.php.net/manual/en/function.file-exists.php ), but if a file exists you must regenerate the file name, so you will iterate each time the file exists.
At last, think to use full time date('Ymdhis') format instead off date('Ymd'), it's also better to use timestamp by calling time() function ( http://www.php.net/manual/en/function.time.php )
Anas,
if (file_exists($random_digit)) {
$random_digit = rand(0000,9999);
}

Categories