das: Wysiwyg-Editoren erzeugen html tags?

hallo!
nachdem ich jetzt schon ewig nach einer Lösung gegoogelt habe und feststellen musste, dass leider kaum jemand dieses Problem hatte, hoffe ich, dass Ihr mir helfen könnt..

Erstmal, ich lerne gerade über ein tutorial http://www.developphp.com/
cms-fähige Seiten zu erstellen. (über localhost, mit xampp)

Letzter Schritt ist jetzt einen Wysiwyg-Editor einzubauen. Wenn ich jetzt über den Editor (TinyMCE) meine Seite bearbeite, dann erzeugen alle Editoren html-tags um den eigentlichen Text.
Das sieht dann etwa so aus:

<p><strong>Mein Text</strong></p>

Wenn ich den Text ohne Editoren bearbeite funktioniert alles. Durch den Editor steht dann auch bei phpmyadmin folgendes:

&lt;p&gt;&lt;strong&gt;Mein Text&lt;/strong&gt;&lt;/p&gt;

Ich hoffe Ihr könnt mir helfen! Danke schonmal! und hier noch der code:

edit_page

<?php  
session_start();  
/* Created by Adam Khoury @ www.developphp.com */  
include_once "admin_check.php";  
?>  
<?php  
// You should put an if condition here to check that the posted $pid variable is present first thing, I did not do that  
$pid = ereg_replace("[^0-9]", "", $_POST['pid']); // filter everything but numbers for security  
// Query the body section for the proper page  
include_once "../scripts/connect_to_mysql.php";  
$sqlCommand = "SELECT pagetitle, linklabel, pagebody FROM pages WHERE id='$pid' LIMIT 1";  
$query = mysqli_query($myConnection, $sqlCommand) or die (mysqli_error());  
while ($row = mysqli_fetch_array($query)) {  
    $pagetitle = $row["pagetitle"];  
	$linklabel = $row["linklabel"];  
	$pagebody = $row["pagebody"];  
	$pagebody = str_replace("<br />", "", $pagebody);  
}  
mysqli_free_result($query);  
?>  
<!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>Editing Page</title>  
<script type="text/javascript">  
  
function validate_form ( ) {  
    valid = true;  
    if ( document.form.pagetitle.value == "" ) {  
	alert ( "Please enter the page title." );  
	valid = false;  
	} else if ( document.form.linklabel.value == "" ) {  
	alert ( "Please enter info for the link label." );  
	valid = false;  
	} else if ( document.form.pagebody.value == "" ) {  
	alert ( "Please enter some info into the page body." );  
	valid = false;  
	}  
	return valid;  
}  
</script>  
<style type="text/css">  
<!--  
body {  
	margin-left: 0px;  
	margin-top: 0px;  
	margin-right: 0px;  
}  
-->  
</style>  
<script type="text/javascript" src="jscripts/tiny_mce/tiny_mce.js"></script>  
  
<script type="text/javascript">  
tinyMCE.init({  
	mode : "textareas"  
});  
</script>  
</head>  
  
<body>  
<table width="100%" border="0" cellpadding="8">  
  <tr>  
    <td><h3>Editing Existing Page&nbsp;&nbsp;&bull;&nbsp;&nbsp; <a href="index.php">Admin Home</a> &nbsp;&nbsp;&bull;&nbsp;&nbsp;<a href="../" target="_blank">View Live Website</a></h3></td>  
  </tr>  
  <tr>  
    <td><?php echo $error_message; ?><br /></td>  
  </tr>  
  <tr>  
    <td>  
  
<table width="100%" border="0" cellpadding="5">  
    <form id="form" name="form" method="post" action="page_edit_parse.php"  onsubmit="return validate_form ( );">  
  <tr>  
    <td width="12%" align="right" bgcolor="#F5E4A9">Page Full Title</td>  
    <td width="88%" bgcolor="#F5E4A9"><input name="pagetitle" type="text" id="pagetitle" size="80" maxlength="64" value="<?php echo $pagetitle; ?>" /></td>  
  </tr>  
  <tr>  
    <td align="right" bgcolor="#D7EECC">Link Label</td>  
    <td bgcolor="#D7EECC"><input name="linklabel" type="text" id="linklabel" maxlength="24"  value="<?php echo $linklabel; ?>" />  
      (What the link to this page will display as)</td>  
  </tr>  
  <tr>  
    <td align="right" valign="top" bgcolor="#DAEAFA">Page Body</td>  
    <td bgcolor="#DAEAFA"><textarea name="pagebody" id="pagebody" cols="88" rows="16"><?php echo $pagebody; ?></textarea></td>  
  </tr>  
  <tr>  
    <td>&nbsp;</td>  
    <td>  
    <input name="pid" type="hidden" value="<?php echo $pid; ?>" />  
    <input type="submit" name="button" id="button" value="Submit Page Edit" /></td>  
  </tr>  
  </form>  
</table>  
  
  
    </td>  
  </tr>  
</table>  
</body>  
</html>

edit_page_parse

<?php  
/* Created by Adam Khoury @ www.developphp.com */  
  
// You may want to obtain refering site name that this post came from for security purposes here  
// exit the script if it is not from your site and script  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
$pid = $_POST['pid'];  
$pagetitle = $_POST['pagetitle'];  
$linklabel = $_POST['linklabel'];  
$pagebody = $_POST['pagebody'];  
// Filter Function -------------------------------------------------------------------  
function filterFunction ($var) {  
    $var = nl2br(htmlspecialchars($var));  
    $var = eregi_replace("'", "&#39;", $var);  
    $var = eregi_replace("`", "&#39;", $var);		  
    return $var;  
}  
$pagetitle = filterFunction($pagetitle);  
$linklabel = filterFunction($linklabel);  
$pagebody = filterFunction($pagebody);  
// End Filter Function --------------------------------------------------------------  
include_once "../scripts/connect_to_mysql.php";  
// Add the updated info into the database table  
$query = mysqli_query($myConnection, "UPDATE pages SET pagetitle='$pagetitle', linklabel='$linklabel', pagebody='$pagebody', lastmodified='now()' WHERE id='$pid'") or die (mysqli_error($myConnection));  
  
echo 'Operation Completed Successfully! <br /><br /><a href="index.php">Click Here</a>';  
exit();  
?>
  1. // Filter Function -------------------------------------------------------------------
    function filterFunction ($var) {
        $var = nl2br(htmlspecialchars($var));
        $var = eregi_replace("'", "&#39;", $var);
        $var = eregi_replace("`", "&#39;", $var);
        return $var;
    }
    $pagetitle = filterFunction($pagetitle);
    $linklabel = filterFunction($linklabel);
    $pagebody = filterFunction($pagebody);
    // End Filter Function --------------------------------------------------------------

    Ist ja wohl klar, dass diese Funktion allen HTML Code aus dem Formular maskiert.
    Wenn du das nicht willst, musst du dir eine ganze Reihe von Sicherheitsmassnahmen einbauen.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
    1. Ist ja wohl klar, dass diese Funktion allen HTML Code aus dem Formular maskiert.
      Wenn du das nicht willst, musst du dir eine ganze Reihe von Sicherheitsmassnahmen einbauen.

      hi, wenn man diese zeile $var = nl2br(htmlspecialchars($var)); aus dem code löscht funktioniert es!

      entsteht dadurch eine Sicherheitslücke?

      1. Ist ja wohl klar, dass diese Funktion allen HTML Code aus dem Formular maskiert.
        Wenn du das nicht willst, musst du dir eine ganze Reihe von Sicherheitsmassnahmen einbauen.

        hi, wenn man diese zeile $var = nl2br(htmlspecialchars($var)); aus dem code löscht funktioniert es!

        entsteht dadurch eine Sicherheitslücke?

        Natürlich. <script src="http://evil-scripts.example.org"/>

        mfg Beat

        --
        ><o(((°>           ><o(((°>
           <°)))o><                     ><o(((°>o
        Der Valigator leibt diese Fische
        1. hi, wenn man diese zeile $var = nl2br(htmlspecialchars($var)); aus dem code löscht funktioniert es!

          entsteht dadurch eine Sicherheitslücke?

          Natürlich. <script src="http://evil-scripts.example.org"/>

          sofern der bereich durch ein passwort geschützt ist, dürfte es doch eig keine Sicherheitsprobleme geben oder?

          hab jetzt noch ein kleines problem..
          wenn man diese zeile löscht wird mein text aus dem wysiwyg-editor zwar richtig (also ohne html-tags) geschrieben, allerdings entsteht jetzt jedesmal zuerst ein absatz, sodass mein text erst in der 2. zeile beginnt. ?

  2. Hallo,

    das wird bei dir am htmlspecialchars() liegen. Diese Funktion wandelt die besonderen in HTML genutzten Zeichen um.

    Ich habe es bei mir so gelöst (auch mit TinyMCE):
    1. Ich speichere eine Variable in der ich htmlspecialchars auf den POST-Wert aus tinyMCE anwende.
    2. DAnn wende ich die Klasse "Inputfilter" auf diese Variable an (Damit kannst du bequem nur bestimmte Tags und Attribute zulassen
    3. Dann wird es in MySQL gespeichert.
    -->Jetzt steht alles so in der DB, dass man es gleich über echo als normales HTML ausgeben kann.

    Wenn ich zum Ändern den Text wieder in den Editor lade wende ich auf die Variable (die dann aus der DB kommt) wieder htmlspecialchars an.

    So klappt es bei mir super - habe viel getestet. Es hört sich mit dem htmlspecialchars komisch an, aber nur so hat es funktioniert, den HTML Code sauber hinzubekommen und dass trotzem noch alle Zeichen dargestellt werden können, die so in den Editor eingetippt werden...
    Es geht sicher noch besser/einfacher, aber ich habe alle Möglichkeiten ausprobiert, die mir eingefallen sind...

    Vielleicht hilft dir das ja weiter.

    Gruß
    alex

    1. Ich habe es bei mir so gelöst (auch mit TinyMCE):

      1. Ich speichere eine Variable in der ich htmlspecialchars auf den POST-Wert aus tinyMCE anwende.
      2. DAnn wende ich die Klasse "Inputfilter" auf diese Variable an (Damit kannst du bequem nur bestimmte Tags und Attribute zulassen
      3. Dann wird es in MySQL gespeichert.
        -->Jetzt steht alles so in der DB, dass man es gleich über echo als normales HTML ausgeben kann.

      Wenn ich zum Ändern den Text wieder in den Editor lade wende ich auf die Variable (die dann aus der DB kommt) wieder htmlspecialchars an.

      So klappt es bei mir super - habe viel getestet. Es hört sich mit dem htmlspecialchars komisch an, aber nur so hat es funktioniert, den HTML Code sauber hinzubekommen und dass trotzem noch alle Zeichen dargestellt werden können, die so in den Editor eingetippt werden...
      Es geht sicher noch besser/einfacher, aber ich habe alle Möglichkeiten ausprobiert, die mir eingefallen sind...

      cool danke! ich versuche das dann morgen mal zu verstehen :)

    2. Lieber Alex,

      1. Ich speichere eine Variable in der ich htmlspecialchars auf den POST-Wert aus tinyMCE anwende.

      Damit werden doch alle Tags von <p> nach &lt;p&gt; umgewandelt, oder? Löst das irgendein Problem?

      1. DAnn wende ich die Klasse "Inputfilter" auf diese Variable an (Damit kannst du bequem nur bestimmte Tags und Attribute zulassen

      Und wie sieht diese Funktion (bzw. Klasse) aus?

      1. Dann wird es in MySQL gespeichert.

      Ach, ohne davor SQL-Injektionen auszufiltern? Soetwas wie mysql(i)_real_escape_string() z.B.?

      -->Jetzt steht alles so in der DB, dass man es gleich über echo als normales HTML ausgeben kann.

      Wenn ich zum Ändern den Text wieder in den Editor lade wende ich auf die Variable (die dann aus der DB kommt) wieder htmlspecialchars an.

      Das klingt vernünftig.

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Hallo Felix,

        1. Ich speichere eine Variable in der ich htmlspecialchars auf den POST-Wert aus tinyMCE anwende.

        Damit werden doch alle Tags von <p> nach &lt;p&gt; umgewandelt, oder? Löst das irgendein Problem?

        Wie gesagt, ich verstehe es selbst nicht ganz, wieso das nötig ist, aber es funktioniert. Im Inputfilter wird es dann wohl wieder umgewandelt, dass am Ende das Richtige rauskommt. Ich habe als ich mir das zusammengebaut habe ewig rumprobiert, damit der Text am Ende genau so rauskommt wie man es eingibt (bzw. wie ich es will). Bei Zeiten werde ich mir das nochmal genauer ansehen...

        1. DAnn wende ich die Klasse "Inputfilter" auf diese Variable an (Damit kannst du bequem nur bestimmte Tags und Attribute zulassen

        Und wie sieht diese Funktion (bzw. Klasse) aus?

        Das trägt zugegeben nicht zur Problemlösung bei sondern sollte ein zusätzlicher Tipp sein. Aber wie oben beschrieben braucht man diesen Schritt zumindest in meinem Lösungsweg - ansonsten hat man ja die htmlspecialchars Variante...

        Ach, ohne davor SQL-Injektionen auszufiltern? Soetwas wie mysql(i)_real_escape_string() z.B.?

        »»
        Natürlich nicht ;)
        Habe nur vergessen es zu erwähnen, weil das in einem anderen Teil vom Skript bei mir passiert. Direkt im SQL Query.

        Gruß
        Alex

        1. Lieber Alex,

          Wie gesagt, ich verstehe es selbst nicht ganz, wieso das nötig ist, aber es funktioniert.

          dann ist Dein Lösungshinweis für den OP völlig wertlos.

          Im Inputfilter wird es dann wohl wieder umgewandelt, dass am Ende das Richtige rauskommt.

          Solange hier keine Referenz oder gar Code dieses ominösen Inputfilters gepostet werden, bleibt Dein Lösungshinweis wertlos.

          Ich habe als ich mir das zusammengebaut habe ewig rumprobiert, damit der Text am Ende genau so rauskommt wie man es eingibt (bzw. wie ich es will).

          Tja, und der Erkenntnisgewinn ist gleich null. Für den OP als Lösungshinweis völlig wertlos. Oder soll der auch eine "black box" anwenden, bei der irgendwie durch Zauberei am Ende das Gewünschte herauskommt? Was macht der im Fall, dass Änderungen zu einem unerwünschten Verhalten führen? Soll er dann wieder "ewig rumprobieren", und am Ende vielleicht sogar scheitern?

          Und wie sieht diese Funktion (bzw. Klasse) aus?

          Das trägt zugegeben nicht zur Problemlösung bei sondern sollte ein zusätzlicher Tipp sein.

          Das ist ja gerade das nicht hilfreiche: Du verschweigst die (genauere) Funktionalität einer wesentlichen Komponente Deines Lösungsansatzes!

          Ach, ohne davor SQL-Injektionen auszufiltern? Soetwas wie mysql(i)_real_escape_string() z.B.?
          »»
          Natürlich nicht ;)
          Habe nur vergessen es zu erwähnen, weil das in einem anderen Teil vom Skript bei mir passiert. Direkt im SQL Query.

          Und der OP könnte diesen Hinweis nicht gebrauchen? Meinst Du, dass das alles sowieso völlig offensichtlich und logisch für Leute ist, die die Innereien Deines Codes nicht kennen?

          Das nenne ich keine Hilfe. Aber der OP war anscheinend glücklich... mal sehen, wie lange.

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Hallo Felix,

            dann ist Dein Lösungshinweis für den OP völlig wertlos.

            Das muss er ja beurteilen ;)
            Jeder darf seine Tipps hier geben - einer wirds dann schon ins schwarze treffe.

            Solange hier keine Referenz oder gar Code dieses ominösen Inputfilters gepostet werden, bleibt Dein Lösungshinweis wertlos.

            Die Klasse heißt "Inputfilter". Ich habe auch rein über den Namen von der Klasse erfahren und sie bequem über Google finden können.

            Tja, und der Erkenntnisgewinn ist gleich null. Für den OP als Lösungshinweis völlig wertlos. Oder soll der auch eine "black box" anwenden, bei der irgendwie durch Zauberei am Ende das Gewünschte herauskommt? Was macht der im Fall, dass Änderungen zu einem unerwünschten Verhalten führen? Soll er dann wieder "ewig rumprobieren", und am Ende vielleicht sogar scheitern?

            Das ist ja gerade das nicht hilfreiche: Du verschweigst die (genauere) Funktionalität einer wesentlichen Komponente Deines Lösungsansatzes!

            »»
            Ich bin normalerweise auch kein Freund von irgendwelchen vorgefertigten Lösungen und baue mein Zeug lieber selber und weiß dann auch was, wie funktioniert - aber manchmal ist es einfach praktisch. Dann benutze ich auch mal sowas und empfehle es auch weiter.
            (Übrigens, das ist keine Riesenklasse - man kann sich dann auch anschauen wie es funktioniert)

            Natürlich nicht ;)
            Habe nur vergessen es zu erwähnen, weil das in einem anderen Teil vom Skript bei mir passiert. Direkt im SQL Query.

            Und der OP könnte diesen Hinweis nicht gebrauchen? Meinst Du, dass das alles sowieso völlig offensichtlich und logisch für Leute ist, die die Innereien Deines Codes nicht kennen?

            Ja, ich denke, dass jeder der das nicht kennt und kappiert ein Idiot ist!

            Nein, natürlich nicht - wie gesagt, das DB Zeugs findet in einem anderen Teil (andere Datei) statt. Ich habe als ich das Posting geschrieben habe schnell in der einen Datei nachgeschaut, wie ich das da mit der Eingabe-Variable gelöst habe - das habe ich abgeschrieben und gut wars...

            Das nenne ich keine Hilfe. Aber der OP war anscheinend glücklich... mal sehen, wie lange.

            ... das Posting habe ich geschriben, weil ich erst letztens vor der Umstellung von meinem selbstgebauten auf den TinyMCE-Editor stand und weil mir dieses Forum auch schon sehr oft geholfen hat und ich gehofft habe, dass ich so etwas zurückgeben kann.

            Wenn ich mehr Zeit habe, dann antworte ich auch ausführlicher. Dann hätte ich mir auch die Klasse angeschaut und dann wäre bestimmt auch das Escapen für MySQL dabei gewesen.

            Gruß
            Alex