...

View Full Version : A very very weird PHP problem



Noonga
02-22-2012, 02:22 PM
This is line 1 of '/opt/index.html' before the fwrite() operation.


$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


This is the fwrite() code:


$fp = fopen('/opt/index.html', 'r+');
fwrite($fp, '<?php
session_start();
$id = "'.mysql_real_escape_string($_POST['id']).'";
');
fclose ($fp);


This is what I was expecting to be in '/opt/index.html' after fwrite() has taken place:


<?php
session_start();
$id = "21";
$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


... but this is what I got:


<?php
session_start();
$id = "21";'testusr', 'testpw') or exit("SERVER ERROR");


Why is this happening?

themousemaster
02-22-2012, 02:33 PM
Not sure why it isn't working, but you can probably force the issue by putting a \n or a \r\n between

$_POST['id']).'

and

";

Noonga
02-22-2012, 02:35 PM
Your example is confusing. Could you please demonstrate it?

Fou-Lu
02-22-2012, 02:45 PM
Where's the code that writes this block of text? Its not present in your OP.

Noonga
02-22-2012, 03:24 PM
Its there. Look carefully and you shall see. :D

Rowsdower!
02-22-2012, 03:28 PM
It looks to me like it's line-breaking just fine. You got two line breaks where you wanted them. The problem you are having is just that it is writing your data over the existing text in the file rather than simply inserting it. This overwriting just happens to include, among other things, a line break that you intended to have between your $id and $link variable assignments.


In trying to post possible solutions to the problem I have noticed that the PHP code box is filtering out backslashes and single quotation marks in an unexpected manner. Looks like a bug. :(

I'm writing to mods to check into it...

Noonga
02-22-2012, 03:38 PM
Yes. I noticed that bug too. How ironic, a coding forums with bugs. :P

How should I go about stopping the overwrite?

Rowsdower!
02-22-2012, 03:44 PM
Can you re-post your code using the standard code box instead of the PHP code box? Parts of your code have been lost and I wouldn't want to work on incomplete information (which is why I didn't bother posting the code pieces I was thinking of before - the landscape changed when I realized that your code does not match what we see in the forum post, so my initial thoughts on the solution are probably moot).

Nevermind. I found this on php.net (http://www.php.net/manual/en/function.fopen.php#93272):


Mikhail Nemtsev 31-Aug-2009 04:27
As someone has mentioned already, using fopen() in r+ mode overwrites the beginning of the file with new data. So, if you want to append new data to the beginning of the file, do so as follows:

<?php
$filename = "myfile.txt";
//first, obtain the data initially present in the text file
$ini_handle = fopen($filename, "r");
$ini_contents = fread($ini_handle, filesize($filename));
fclose($ini_handle);
//done obtaining initially present data

//write new data to the file, along with the old data
$handle = fopen($filename, "w+");
$writestring = "text to write to file\n" . $ini_contents;
if (fwrite($handle, $writestring) === false) {
echo "Cannot write to text file. <br />";
}
fclose($handle);
?>

I assumed r+ would allow prepending but apparently it overwrites. You need to copy the existing file data, prepend your new string, and then rewrite the ENTIRE file.

Fou-Lu
02-22-2012, 07:00 PM
Its there. Look carefully and you shall see. :D

I'm still not seeing where this:


$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");

Is written to the file. Since we can't see where its being written we cannot diagnose that issue (which is the issue).

There is no such thing as a prepend option in a file write. The only way to really do that is to determine the length to write, move the existing data further by that length, seek back to the original location and insert. An alternative as posted above does the same but captures the previous data in the block. There's no reason to use two opens though, just an r+ is sufficient.


Sorry, if you use my route r+ is sufficient. If you use the above you can use r+ but only if you execute an ftruncate as well. If its a prepend, logically it doesn't need to be truncated, but I would suggest doing so nonetheless.

Rowsdower!
02-22-2012, 07:21 PM
I'm still not seeing where this:


$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");

Is written to the file...

I think that's the part that is already in the file (that is what we are prepending in front of, but is being overwritten). So we do indeed see where he writes to the file, but we don't see the original file contents.

Or at least that's my interpretation.

Fou-Lu
02-22-2012, 08:15 PM
oh I see, hence the discussion on prepend.

Noonga
02-23-2012, 12:23 AM
Here is the code in CODE brackets:

This is line 1 of '/opt/index.html' before the fwrite() operation.


$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


This is the fwrite() code:


$fp = fopen('/opt/index.html', 'r+');
fwrite($fp, '<?php
session_start();
$id = "'.mysql_real_escape_string($_POST['id']).'";
');
fclose ($fp);


This is what I was expecting to be in '/opt/index.html' after fwrite() has taken place:


<?php
session_start();
$id = "21";
$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


... but this is what I got:


<?php
session_start();
$id = "21";'testusr', 'testpw') or exit("SERVER ERROR");

Rowsdower!
02-23-2012, 03:01 PM
Here is the code in CODE brackets:

This is line 1 of '/opt/index.html' before the fwrite() operation.


$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


This is the fwrite() code:


$fp = fopen('/opt/index.html', 'r+');
fwrite($fp, '<?php
session_start();
$id = "'.mysql_real_escape_string($_POST['id']).'";
');
fclose ($fp);


This is what I was expecting to be in '/opt/index.html' after fwrite() has taken place:


<?php
session_start();
$id = "21";
$link = mysql_connect('testusr', 'testpw') or exit("SERVER ERROR");


... but this is what I got:


<?php
session_start();
$id = "21";'testusr', 'testpw') or exit("SERVER ERROR");


Did you see my "edit" in post #8? The problem has been identified; fwrite() will not prepend or insert on its own. It just plain writes based on its current pointer location so you need to manually adjust for that.

The code in post #8 is not ideal, though - it's just the first functional method that I found on google. I reread the PHP documentation notes for fread() (http://us3.php.net/manual/en/function.fread.php) today and saw that file_get_contents() (http://us3.php.net/manual/en/function.file-get-contents.php) is more efficient to use if all you want to do is get the entire contents of a file (which we would, in this case). The fwrite() (http://us3.php.net/manual/en/function.fwrite.php) docs have no similar notes regarding file_put_contents() (http://us3.php.net/manual/en/function.file-put-contents.php) - which is the complimentary function for writing date - so I checked the docs for the file_put_contents() function itself and found that it is said to be literally "identical" to calling fopen(), fwrite(), and fclose() in succession.

So in that case, I think this would be the way to go in order to save on heartache:

<?php
//set file location
$file = "/opt/index.html";
//set string to prepend to file
$prepend_string = '<?php\n session_start();\n $id = "'.mysql_real_escape_string($_POST['id']).'";\n';
//copy existing file data
$existing_data = file_get_contents($file);
//write prepend string and existing data concatenated together, and perform this task with an error check
if(file_put_contents($file,$prepend_string.$existing_data)===false){
//if the file writing failed and returned "false" we alert the user to the problem
print "Error writing to file...";
}
?>



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum