...

View Full Version : PHP write to txt: special characters



TomD
08-22-2009, 12:28 PM
I am trying to get a very simple guestbook working, without using MySQL. Submitting a message (through a form) calls a php-script that adds the new entry to a plain txt-file. It works, but special characters such as "é" don't work, they become something like "é". I have found that this can be solved with utf-8 encoding, but I didn't manage to get this to work yet.

I am only using and adjusting a free available script, I don't know too much about php myself. :o

The form:


<form action="act.php" method="post">
<p>Name<br />
<input name="name" type="text" class="textfield" value="" size="20" /></p>
<p>Message<br />
<textarea class="textarea" rows="4" cols="30" name="message"></textarea></p><br />
<input type="submit" name="send" value="Send" />
<input type="reset" name="reset" value="Reset" />
</form>

Relevant parts of act.php:

<?php
function clean($str) {
$str = stripslashes ( $str );
$str = htmlentities ( $str );
$str = strip_tags ( $str );
$str = utf8_encode ( $str );
return $str;
}
// Get the data from the 'Name' field of the form.
$data = '<b>'.$_POST['name'].'</b>'.'<span class="date"> (' . date('d.m.Y H:i') .') </span>'.'<br />';
// Get the data from the 'site' field of the form.
// $data = $data.'<b>Web site: </b>'.'<a href="http://'.$_POST['site'].'">'.$_POST['site'].'</a>'.'<br />';
// Get the data from the 'Message' field of the form.
$data = $data.'<p><span class="gbp">'.clean($_POST["message"]).'</span></p><hr />';

// The file to write $data to (don't forget to CHMOD it to 666).
$file = "messages.txt";
$new = stripslashes($data) . "\n" . implode( '' , file( $file ) );


if (!$file_handle = fopen($file,"w"))
{
echo "Cannot open file";
}
if (!fwrite($file_handle,utf8_encode($new)))
{
echo "Cannot write to file";
}
fclose($file_handle);

echo ('<meta http-equiv="Refresh" content="0;url=bedankt_gb.php" />');
}
}
?>

For example, with two test entries, the messages.txt file looks like this:

<b>Tom</b>
<span class="date"> (22.08.2009 13:16) </span><br />
<p><span class="gbp">h&Atilde;&copy;h &Atilde;&copy; test h&Atilde;&uml;</span></p>
<hr />
<b>Tom</b>
<span class="date"> (22.08.2009 13:13) </span><br />
<p><span class="gbp">h&Atilde;&copy; hehe ok @ tom</span></p>
<hr />

If anyone could help, thanks!

Phil Jackson
08-22-2009, 02:42 PM
My advice being remove all diff functions that you've used for encoding and use this when loading/defining your data, i.e.

$data = blabla;

to



$data = blabla;
$data = mb_convert_encoding($data, 'HTML-ENTITIES', "UTF-8");

and use the same just before you write to your file.

TomD
08-22-2009, 02:47 PM
I seem to have a problem with that function:

"Fatal error: Call to undefined function: mb_convert_encoding() in /home/dbvaxel/public_html/act.php on line 14".

Phil Jackson
08-22-2009, 03:36 PM
could you repost your code with the alterations?

TomD
08-22-2009, 04:20 PM
Hm, I reverted it and kind of messed up the code.

Do I have to remove the cleaning function as well (if I drop the utf-encoding there, adding it where you suggest) or do I have to keep this?


function clean($str) {
$str = stripslashes ( $str );
$str = htmlentities ( $str );
$str = strip_tags ( $str );
return $str;
}

TomD
08-22-2009, 04:42 PM
Perhaps it's not the most efficient way to try and fix my current code since that is already a mix of various things I tried and partial solutions I found online. For more experienced php-users, I guess it's not hard to do this in a few lines. I'll try to explain what needs to happen, hopefully this is something that can be done easily.

The information for a new entry comes from the form I gave in my first post; it contains "name" and "message". It is sent to act.php, which needs to process the new entry. For a new entry, I want the following expression added to the top of the messages.txt file (which I saved in notepad with "UTF-encoding"):

<b>name</b><span class="date"> (date) </span><br /><p><span class="gbp">message</span></p><hr />

The variables in bold need to be the data from the form (supporting special characters), the date in italic should be added with a php-function. The contents of messages.txt is just read by a html file, styled via css.

Because the standard php-functions that write to a file add to the bottom of the file (or top, but then they overwrite), I use the following trick: store the current contents of messages.txt in a variable and adding the new entry to this variable, with ($data refers to the data of the new entry):


$file = "messages.txt";
$new = stripslashes($data) . "\n" . implode( '' , file( $file ) );

Because I've been adding encode-utf functions in all kinds of places, it may be better to start from scratch. Thanks in advance!

Phil Jackson
08-22-2009, 05:41 PM
<?php
function clean($str) {
$str = strip_tags ( $str );
return $str;
}
// Get the data from the 'Name' field of the form.
$data = '<b>'.$_POST['name'].'</b>'.'<span class="date"> (' . date('d.m.Y H:i') .') </span>'.'<br />';
// Get the data from the 'site' field of the form.
// $data = $data.'<b>Web site: </b>'.'<a href="http://'.$_POST['site'].'">'.$_POST['site'].'</a>'.'<br />';
// Get the data from the 'Message' field of the form.
$data = $data.'<p><span class="gbp">'.clean($_POST["message"]).'</span></p><hr />';

// The file to write $data to (don't forget to CHMOD it to 666).
$file = "messages.txt";
$new = stripslashes($data) . "\n" . implode( '' , file( $file ) );


if (!$file_handle = fopen($file,"w"))
{
echo "Cannot open file";
}
if (!fwrite($file_handle,utf8_encode($new)))
{
echo "Cannot write to file";
}
fclose($file_handle);

echo ('<meta http-equiv="Refresh" content="0;url=index.html" />');

?>




<form action="act.php" method="post">
<p>Name<br />
<input name="name" type="text" class="textfield" value="" size="20" /></p>
<p>Message<br />
<textarea class="textarea" rows="4" cols="30" name="message"></textarea></p><br />
<input type="submit" name="send" value="Send" />
<input type="reset" name="reset" value="Reset" />
</form>

<?php

$file = file_get_contents("messages.txt");
$file = mb_convert_encoding($file, 'HTML-ENTITIES', "UTF-8");
echo $file;
?>



Just see if this works as i think this is what your after.

Phil Jackson
08-22-2009, 05:43 PM
just save them in a new folder and seperate files - act.php and index.php

barkermn01
08-22-2009, 05:51 PM
I'm i missing some thing php can handle special characters in quotes E.G
"©" the only problem is HTML cant output it if you saving to a TEXT file just use the quotes and the char,

If thats the case dont use UTF8

htmlspecialchars()



<?php
$file = file_get_contents("messages.txt");
$file = htmlspecialchars($file);
echo $file;
?>

Phil Jackson
08-22-2009, 05:52 PM
sorry this one


<form action="act.php" method="post">
<p>Name<br />
<input name="name" type="text" class="textfield" value="" size="20" /></p>
<p>Message<br />
<textarea class="textarea" rows="4" cols="30" name="message"></textarea></p><br />
<input type="submit" name="send" value="Send" />
<input type="reset" name="reset" value="Reset" />
</form>

<?php

$file = file_get_contents("messages.txt");
$file = utf8_decode($file);
echo $file;
?>

TomD
08-23-2009, 11:14 AM
Thanks Phil. This seems to be partially working, I think I didn't do the "decode" step when outputting the messages.txt file. But now, only the last added entry is correctly displayed. When adding a new one, the old ones lose the correct special characters. Do I have to add some decode/encode-step when storing the old contents in the file-variable to add a new entry?

Phil Jackson
08-23-2009, 11:28 AM
can you show me the scripts that you have now altered and the message.txt (if possible) and will take a look.

TomD
08-23-2009, 11:42 AM
Alright, I started from a clean (empty) messages.txt file, saved in UTF-8-format with notepad. I'm using the exact php-code you posted as act.php. I'm also using your (last) piece of code to show the entries. So I assume I don't need to copy them, I didn't make any alterations.

I first added: Tétrisö. This is then shown correctly and messages.txt looks like this:

<b>Tom</b><span class="date"> (23.08.2009 12:36) </span><br /><p><span class="gbp">Tétrisö</span></p><hr />

Although the signs are "crazy" here, the output is shown correctly as "Tétrisö" on the site. Then I added "Tétrisö" again as a second entry. Now only this new message is shown correctly, the first one is again with "crazy signs". The contents of messages.txt is now:

<b>Tom2</b><span class="date"> (23.08.2009 12:40) </span><br /><p><span class="gbp">Tétrisö</span></p><hr />
<b>Tom</b><span class="date"> (23.08.2009 12:36) </span><br /><p><span class="gbp">Tétrisö</span></p><hr />

It is shown in the output as:

Tom2 (23.08.2009 12:40)
Tétrisö
Tom (23.08.2009 12:36)
Tétrisö

My guess is that when the old entries are read from messages.txt and stored in a variable where the new entry is added, also some en- or decoding needs to be done?

Phil Jackson
08-23-2009, 11:54 AM
am i correct in assuming you altered your function to:



function clean($str) {
$str = strip_tags ( $str );
return $str;
}

TomD
08-23-2009, 11:56 AM
Yes, I'm now using your exact code of this post (http://www.codingforums.com/showpost.php?p=856639&postcount=7) for act.php.

Phil Jackson
08-23-2009, 12:06 PM
ok sorted it 2 mins..

Phil Jackson
08-23-2009, 12:07 PM
<?php
function clean($str) {
$str = strip_tags ( $str );
$str = mb_convert_encoding($str, 'HTML-ENTITIES', "UTF-8");
return $str;
}
// Get the data from the 'Name' field of the form.
$data = '<b>'.$_POST['name'].'</b>'.'<span class="date"> (' . date('d.m.Y H:i') .') </span>'.'<br />';
// Get the data from the 'site' field of the form.
// $data = $data.'<b>Web site: </b>'.'<a href="http://'.$_POST['site'].'">'.$_POST['site'].'</a>'.'<br />';
// Get the data from the 'Message' field of the form.
$data = $data.'<p><span class="gbp">'.clean($_POST["message"]).'</span></p><hr />';

// The file to write $data to (don't forget to CHMOD it to 666).
$file = "messages.txt";
$new = stripslashes($data) . "\n" . implode( '' , file( $file ) );


if (!$file_handle = fopen($file,"w"))
{
echo "Cannot open file";
}
if (!fwrite($file_handle, $new))
{
echo "Cannot write to file";
}
fclose($file_handle);

echo ('<meta http-equiv="Refresh" content="0;url=index.php" />');

?>




<form action="act.php" method="post">
<p>Name<br />
<input name="name" type="text" class="textfield" value="" size="20" /></p>
<p>Message<br />
<textarea class="textarea" rows="4" cols="30" name="message"></textarea></p><br />
<input type="submit" name="send" value="Send" />
<input type="reset" name="reset" value="Reset" />
</form>

<?php

$file = file_get_contents("messages.txt");
$file = mb_convert_encoding($file, 'HTML-ENTITIES', "UTF-8");
echo $file;
?>

TomD
08-23-2009, 12:09 PM
There seems to be a problem with that function, I get:

"Fatal error: Call to undefined function: mb_convert_encoding() in /home/dbvaxel/public_html/contact.php on line 74"

Phil Jackson
08-23-2009, 12:14 PM
im getting no error this end... what other code do you have in place (all working perfect) (i have no line 74 you see)

TomD
08-23-2009, 12:23 PM
Well the page that contains the guestbook has a menu and some stuff, which is my page is larger. But it doesn't contain any php code that could be conflicting, I think. I've googeled this error and this appears to be something that requires fixing on the level of the server :(

Phil Jackson
08-23-2009, 12:26 PM
ah.. ok, it is suported by PHP 4 & 5.... ill see what i can find

TomD
08-23-2009, 12:28 PM
Strange, PHP 5.2.6 is installed on the server...

Phil Jackson
08-23-2009, 12:32 PM
ah yes.
check to see if multi byte string functions are enabled in your server.

TomD
08-23-2009, 12:33 PM
How can I check that? :o

barkermn01
08-23-2009, 12:37 PM
in your php.ini
Google (google.com/search?q=php%20how%20to%20enable%20multi%20byte%20string%20functions)

I hope your not debian based it meens a recompile,
if windows there should be an extension="mbstring.dll"
or if REHL based "yum install php-mbstring" should enable it for you

Fedora CentOS or REHL can all use the Yum function you can try with debian based the apt-get install php-mbstring that might not work though

Phil Jackson
08-23-2009, 12:37 PM
php ini file

mbstring.func_overload setting

Phil Jackson
08-23-2009, 12:38 PM
or any relating (not sure you see)

Phil Jackson
08-23-2009, 12:39 PM
there is a list here

http://osdir.com/ml/php.internationalization/2003-12/msg00004.html

TomD
08-23-2009, 12:45 PM
Sorry, I've never worked with this php.ini file. I didn't know how to access it but I found on this page (http://www.washington.edu/computing/web/publishing/php-ini.html) that it can be found at "/usr/local/lib/php/php.ini-dist" but I don't seem to have acces to /usr when I go to my root directory (I have public_html, tmp, logs, ... but no usr)...?

Phil Jackson
08-23-2009, 12:51 PM
get in touch with your provider. tell them what you want doing and they should sort it if you are able to change ini settings.

TomD
08-23-2009, 02:06 PM
Alright, I contacted the hosting provider to check this out. If that doesn't solve the problem, is there a way to do it with the functions you previously used? Those seemed to work and the script almost did what it had to do. Thanks for your help so far!

It probably would've been a lot easier to just use a standard php/mysql-guestbook script but I like the fact that this integrates flawlessly in the rest of the website and I don't need/want all the special extra functions those advanced scripts offer - just this plain simple guestbook is fine :)

Phil Jackson
08-23-2009, 04:13 PM
i've dibled and dabled in all kinds of ways when it comes to encoding and displaying correct output (i've been developing a plug n play CMS for the past year and encoding is a huge area) and mb_convert_encoding is by far the best function to use. I'll set up a test page for you to see the results.

http://www.actwebdesigns.co.uk/codingforumhelp/

TomD
08-23-2009, 05:04 PM
Hm yes, it works nicely for you. The messages.txt contains the codes ("T&eacute" etc) while my messages.txt still has these "crazy chars" :confused:

Edit: is there a difference in the way you process the name and the message? Because for the name, your messages.txt now also shows "Tomé" instead of "Tom&eacute;".

Phil Jackson
08-23-2009, 05:11 PM
$data = '<b>'.clean($_POST['name']).'</b>'.'<span class="date"> (' . date('d.m.Y H:i') .') </span>'.'<br />';


just edited.

try again
don't worry what's in the message.txt.

TomD
08-23-2009, 05:13 PM
Right, this seems to work fine. Is this the same php-code as before, or did you make any other alterations? If so, could you show the final scripts? Perhaps I can try it on another server to see whether it is indeed my current server causing the problem or conflicting code in my pages.

Phil Jackson
08-23-2009, 05:25 PM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>

<form action="act.php" method="post">
<p>Name<br />
<input name="name" type="text" class="textfield" value="" size="20" /></p>
<p>Message<br />
<textarea class="textarea" rows="4" cols="30" name="message"></textarea></p><br />
<input type="submit" name="send" value="Send" />
<input type="reset" name="reset" value="Reset" />
</form>

<?php

$file = file_get_contents("messages.txt");
$file = mb_convert_encoding($file, 'HTML-ENTITIES', "UTF-8");
echo $file;
?>


</body>
</html>




<?php
function clean($str) {
$str = strip_tags ( $str );
$str = mb_convert_encoding($str, 'HTML-ENTITIES', "UTF-8");
return $str;
}
// Get the data from the 'Name' field of the form.
$data = '<b>'.clean($_POST['name']).'</b>'.'<span class="date"> (' . date('d.m.Y H:i') .') </span>'.'<br />';
// Get the data from the 'site' field of the form.
// $data = $data.'<b>Web site: </b>'.'<a href="http://'.$_POST['site'].'">'.$_POST['site'].'</a>'.'<br />';
// Get the data from the 'Message' field of the form.
$data = $data.'<p><span class="gbp">'.clean($_POST["message"]).'</span></p><hr />';

// The file to write $data to (don't forget to CHMOD it to 666).
$file = "messages.txt";
$new = stripslashes($data) . "\n" . implode( '' , file( $file ) );


if (!$file_handle = fopen($file,"w"))
{
echo "Cannot open file";
}
if (!fwrite($file_handle, $new))
{
echo "Cannot write to file";
}
fclose($file_handle);

echo ('<meta http-equiv="Refresh" content="0;url=index.php" />');

?>

Phil Jackson
08-23-2009, 05:27 PM
if you dont mind me asking, how much you pay and who with.

TomD
08-23-2009, 05:38 PM
Thanks, the code works perfectly on another server.

You mean the hosting provider? The one where it's not working is with PortNap (http://portnap.com/).

Phil Jackson
08-23-2009, 06:01 PM
glad everything's working.

TomD
08-23-2009, 06:03 PM
Well not yet at the server where I want it to work, but that's a problem for my hosting provider - I hope they can fix it so the function works.

Thanks a lot for your patience and help!

Mwnciau
08-23-2009, 09:08 PM
While it's not nearly as efficient, this code will work without the mb_convert_encoding function by converting all unrecognised characters into their HTML equivalent:


function clean ( $str )
{
return preg_replace_callback('#[^]a-z0-9!"£$%^&*()_+=-[{}\'@~\#`¬\\|,.?/]#i', 'charReplace', $str);
}
function charReplace( $match )
{
return '&#' . ord($match[0]) . ';';
}

Alternatively, you could look at this class (http://mikolajj.republika.pl/) mentioned in the manual page for mb_convert_encoding



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum