Multiple fopens - only first one works - php

I've a strange issue I am encountering. Recently I switched from webhosting to a VPS, mainly because of flexibility a VPS provides me with.
I now however need to setup Apache on my own and I'm not to good at doing so.
I've a .php file and I have 2 fopen in it. The first one does it's job but the second one doesn't work for some reason.
I was wondering, is there some php.ini settings I need to make to allow multiple fopen in a file ?
EDIT
Code below:
$fp = fopen('ticket' . $_SESSION['id'] . '.txt', 'a+');
$savestring = "---";
fwrite($fp, $savestring);
fclose($fp);
$_SESSION['total'] = $total;
$fp = fopen('reqs.txt', 'a+');
$savestring = PHP_EOL . "Ticket Nou: " . $_SESSION['id'] . " | Ora: " . $ordertime . " | IP: " . $ip;
fwrite($fp, $savestring);
fclose($fp);
I shortened the $savestrings, in reality they are longer. The issue occurs with the second file, reqs.txt.

try to use flock
I have a file with 4 fopen it didn't work.
after using flock it worked.

Related

PHP: Why file can only be written the first time and subsequent writes fail?

My code:
function log_message($user = "", $message = "") {
$log_file = LOG_PATH;
// if we can open the file
if($handle = fopen($log_file, "a")) {
$timestamp = strftime("%Y-%m-%d:%H %H:%M:%S", time());
$content = $timestamp . " | [{$user}] | " . $message . "\n";
fwrite($handle, $content);
fclose($handle);
} else {
die("error opening log file: {$log_file}");
}
}
Problem:
The first time I can write to the file no problem but any subsequent writes don't get make it through and falls into the else statement?
Other info:
The site is hosted on godaddy and i have set the privacy permissions on the folder to be writable.
What I tried:
I used the function
file_put_contents($log_file, $content . PHP_EOL, FILE_APPEND | LOCK_EX);
but same result.
I also tried the solution mentioned in this question: How to make sure a file handle has been closed before next operation?

file_get_contents doesn't write to a log file

I am trying to write content to a log file using form input data. This doesn't seem to work on a server that's is using php version 5.3.14 but when i put the same code on a server that uses 5.3.27 its working. Does any one have an idea on how to fix this?
Below is my code that i am using for my form action. incoming.log is the file that i am trying to write to and is found in the folder path live/lms on the server. Please not that i am not getting any errors.
<?php
$system_path = '/live/lms/';
$fh = fopen($system_path . "incoming.log", "a");
fwrite($fh, "\nReceived:\n" . date("Y-m-d H:i:s") . "\n" . file_get_contents("php://input"));
fclose($fh);
?>
Not exactly an answer, but advise:
You should add more error handling ...and structure the script in a way so you can add more error handling.
For starters (work in progress):
<?php
$system_path = '/live/lms/';
$fhSource = fopen('php://input', 'rb');
if (!$fhSource) {
trigger_error('fopen input: '. print_r(error_get_last(), true), E_USER_ERROR );
}
$fhTarget = fopen($system_path . "incoming.log", 'a');
if (!$fhTarget) {
trigger_error('fopen output: '. print_r(error_get_last(), true), E_USER_ERROR );
}
$cb = stream_copy_to_stream($fhSource, $fhTarget);
var_dump($cb);
fclose($fhSource);
fclose($fhTarget);

connect master server stream_socket_client

I wrote a script to pull a server list from the master server from Enemy Territory; However it silently fails; I had it working; but for some unknown reason it doesn't anymore.
I used this document to "talk" with the server : http://src.gnu-darwin.org/ports/games/masterserver/work/masterserver-0.4.1/docs/PROTOCOLS
This seems valid since it worked before and it still works on game servers; This is my code :
<?php
// set sv_master1 "etmaster.idsoftware.com"
// set sv_master2 "master0.gamespy.com"
// set sv_master3 "wolfmaster.idsoftware.com"
// set sv_master4 "clanservers.net"
// set sv_master5 "master0.etmaster.net" 213.108.29.23
$host = 'etmaster.idsoftware.com';
$port = '27950';
// $status = chr(255) . chr(255) . chr(255) . chr(255) . chr(0x02) . 'getservers' . chr(0x00);
$status = "\xFF\xFF\xFF\xFFgetservers\x00";
$fp = stream_socket_client("udp://" . $host . ":" . $port, $errno, $errstr, 10);
if (!$fp) {
echo "ERROR: " . $errno . $errstr . "<br>\n";
} else {
fwrite($fp, $status);
//stream_set_timeout($fp, 10); // this is for debugging;
$data = fread($fp, 1024);
fclose($fp);
print_r($data);
}
I attempted 60 seconds execution time (its localhost) but it still doesn't work ... any help is appreciated !
When I check the steps (in cli) the longest time is spend on fread(); but $data contains only an empty string;
The error is small; there had to be 5* \xFF tag; and I only used 4.

PHP lock text file for editing?

I've got a form that writes its input to a textfile.
Would it be possible to lock a text file for editing, and perhaps give a friendly message "the file is edited by another user, please try again later."
I'd like to avoid conflicts if the file has multiple editors at the same time.
Here's how the entry is currently added.
$content = file_get_contents("./file.csv");
$fh = fopen("./file.csv", "w");
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
Any thoughts?
You can use flock() function to lock the file. For more see this
Something like:
<?php
$content = file_get_contents("./file.csv");
$fp = fopen("./file.csv", "w"); // open it for WRITING ("w")
if (flock($fp, LOCK_EX))
{
// do your file writes here
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
flock($fh, LOCK_UN); // unlock the file
}
?>
In order of desirability:
Use a database.
Use more than one text file.
Use locks:
eg:
$lockwait = 2; // seconds to wait for lock
$waittime = 250000; // microseconds to wait between lock attempts
// 2s / 250000us = 8 attempts.
$myfile = '/path/to/file.txt';
if( $fh = fopen($myfile, 'a') ) {
$waitsum = 0;
// attempt to get exclusive, non-blocking lock
$locked = flock($fh, LOCK_EX | LOCK_NB);
while( !$locked && ($waitsum <= $lockwait) ) {
$waitsum += $waittime/1000000; // microseconds to seconds
usleep($waittime);
$locked = flock($fh, LOCK_EX | LOCK_NB);
}
if( !$locked ) {
echo "Could not lock $myfile for write within $lockwait seconds.";
} else {
// write out your data here
flock($fh, LOCK_UN); // ALWAYS unlock
}
fclose($fh); // ALWAYS close your file handle
} else {
echo "Could not open $myfile";
exit 1;
}
You can use PHP's flock function to lock a file for writing, but that lock won't persist across web requests and doesn't work on NFS mounts (at least in my experience).
Your best be may be to create a token file in the same directory, check for its existence and report an error if it exists.
As with any locking scheme, you're going to have race conditions and locks that remain after the operation has completed, so you'll need a way to mitigate those.
I would recommend creating a hash of the file before editing and storing that value in the lock file. Also send that hash to the client as part of the edit form (so it comes back as data on the commit request). Before writing, compare the passed hash value to the value in the file. If they are the same, commit the data and remove the lock.
If they are different, show an error.
You could try flock — Portable advisory file locking ?
http://php.net/manual/en/function.flock.php
I would just use a simple integer or something like that.
$content = file_get_contents("./file.csv");
$fh = fopen("./file.csv", "w");
$status = 1;
...
if($status == 1){
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
$status = 0;
}
else
echo "the file is edited by another user, please try again later.";
Is that what you mean?

Why do I keep getting "directory does not exist?"

I cannot figure out what I am doing wrong here. The permissions for the directory I have for the file being created have write permissions all across the board. I keep getting "directory does not exist" Thanks for the help!
<?
//creates variables and calls the information from the server
$Name = $_POST['name'];
$desc = $_POST['desc'];
$website =$_POST['web'];
$email =$_POST['email'];
$cname =$_POST['cname'];
echo "your registered name is: ". $Name . ".<br/>";
echo "your registered description is: " . $desc . ".<br/>";
echo "your website address is: " . $website . ".<br/>";
echo "your Confirmation email has been sent to: " . $email . ".<br/>";
echo "your information has been stored, thank you! ";
$cname = trim($cname);
$filename = "data/clubinfo/$cname.txt";
$fp = fopen($filename,'a');
fwrite($fp,$Name);
fwrite($fp,"\n");
fwrite($fp,$email);
fwrite($fp,"\n");
fwrite($fp,$desc);
fwrite($fp,"\n");
fwrite($fp, $website);
fwrite($fp, "\n");
fwrite($fp,"__");
fwrite($fp, "\n");
fclose($fp);
?>
Most likely the script is assuming a different working directory to what you're presuming since you're using a relative path.
You'd be better off specifying the path absolutely or at least in relation to $_SERVER['DOCUMENT_ROOT'] even if you do:
$filename = $_SERVER['DOCUMENT_ROOT'] . "../data/clubinfo/$cname.txt";
The advantage of that is that it's outside your document root so it won't be served directly by your Web server. It will also work no matter the location of your script and will work no matter under what directory you install your Webapp, which can be an issue with dev vs prod deployments.
The data/clubinfo folder does not exist in the current directory.
You need to create it first. (By hand or in PHP)
Alternatively, the current directory might not be what you think it is.
Try using file_put_contents() like this:
file_put_contents("data/clubinfo/$cname.txt", implode("\n", $_POST));
If you want to this value by value you should also use the FILE_APPEND flag.
looks like you have not given the path off the root and the server is looking from the current location. try giving the path off the root.

Categories