Problem mit Sessions

graffcon

Mitglied
Hallo Leute,

ich habe folgendes Situation:
In einer Datei wird eine Session gestartet, ein Captcha generiert und der Code als Zeichenkette in der Session gespeichert.

In dem Formular, welches das Captcha verwenden soll, wird (logischerweise) ebenfalls session_start() aufgerufen, die Formular-Eingaben geprüft, u.a. auch, ob der Captcha-Code im Post-Array dem in der Session gespeicherten entspricht. Um den Code im Captcha-Bild und den in der aktuellen Session auf einen Blick vergleichen zu können, gebe ich die Session-Variable aus.

Das Problem:
Beim ersten Aufruf des Formulars wird noch keine Session-Variable im Formular ausgegeben, sie wurde anscheinend in der Captcha-Datei nicht richtig zugewiesen.
Aktualisiert man das Formular nun, wird eine Session-Variable ausgegeben, allerdings enthält diese jetzt den Code, den das Bild im Durchlauf davor hatte...

Die Dateien:

Captcha-Datei:
PHP:
<?php 
    session_start();
    $CAPTCHA_LENGTH = 5;    // Lnge der Captcha-Zeichenfolge, hier fnf Zeichen
    $FONT_SIZE      = 20;   // Schriftgre der Zeichen in Punkt
    $IMG_WIDTH      = 170;  // Breite des Bild-Captchas in Pixel
    $IMG_HEIGHT     = 60;   // Hhe des Bild-Captchas in Pixel

    // Liste aller verwendeten Fonts
    $FONTS[] = '../ttf/Kreditf';
    $FONTS[] = '../ttf/actionjf';
    $FONTS[] = '../ttf/MINYAf';
    $FONTS[] = '../ttf/asylumf';
    $FONTS[] = '../ttf/aarcof';
    $FONTS[] = '../ttf/8-PMf';

    // Unser Zeichenalphabet
    $ALPHABET = array('A', 'B', 'C', 'D', 'E', 'F', 'G',
                      'H', 'Q', 'J', 'K', 'L', 'M', 'N',
                      'P', 'R', 'S', 'T', 'U', 'V', 'Y',
                      'W', '2', '3', '4', '5', '6', '7');

    // Wir teilen dem Browser mit, dass er es hier mit einem JPEG-Bild zu tun hat.
    header('Content-Type: image/jpeg', true);

    // Wir erzeugen ein leeres JPEG-Bild von der Breite IMG_WIDTH und Hhe IMG_HEIGHT
    $img = imagecreatetruecolor($IMG_WIDTH, $IMG_HEIGHT);

    // Wir definieren eine Farbe mit Zufallszahlen
    // Die Farbwerte sind durchgehend und absichtlich hoch (200 - 256) gewhlt,
    // um eine "leichte" Farbe zu erhalten
    $col = imagecolorallocate($img, rand(200, 255), rand(200, 255), rand(200, 255));

    // Wir fllen das komplette Bild mit der zuvor definierten Farbe
    imagefill($img, 0, 0, $col);

    $captcha = ''; // Enthlt spter den Captcha-Code als String
    $x = 10; // x-Koordinate des ersten Zeichens, 10 px vom linken Rand


    for($i = 0; $i < 5; $i++) {

        $chr = $ALPHABET[rand(0, count($ALPHABET) - 1)]; // ein zuflliges Zeichen aus dem definierten Alphabet ermitteln
        $captcha .= $chr; // Der Zeichenfolge $captcha das ermittelte Zeichen anfgen


        $col = imagecolorallocate($img, rand(0, 199), rand(0, 199), rand(0, 199)); // einen zuflligen Farbwert definieren
        $font = $FONTS[rand(0, count($FONTS) - 1)]; // einen zuflligen Font aus der Fontliste FONTS auswhlen


        $y = 25 + rand(0, 20); // die y-Koordinate mit einem Mindestabstand plus einem zuflligen Wert festlegen
        $angle = rand(0, 30); // ein zuflliger Winkel zwischen 0 und 30 Grad

        /*
         * Diese Funktion zeichnet die Zeichenkette mit den
         * gegeben Parametern (Schriftgre, Winkel, Farbe, TTF-Font, usw.)
         * in das Bild.
         */

        imagettftext($img, $FONT_SIZE, $angle, $x, $y, $col, $font, $chr);

        $dim = imagettfbbox($FONT_SIZE, $angle, $font, $chr); // ermittelt den Platzverbrauch des Zeichens
        $x += $dim[4] + abs($dim[6]) + 10; // Versucht aus den zuvor ermittelten Werten einen geeigneten Zeichenabstand zu ermitteln
        
}	
      $_SESSION['captcha'] = $captcha;
      imagejpeg($img); // Ausgabe des Bildes an den Browser

	  imagedestroy($img); // Freigeben von Speicher  
?>

Formular-Datei:
PHP:
<?php
session_start();
include("../skripte/connect.inc.php");

if(isset($_POST['submit']))
{
  $errmsg = "";
  $sql = "INSERT INTO guestbook (guestbook_name,guestbook_homepage,guestbook_text,guestbook_datetime) VALUES(";
  
  // Korrekte Mail-Adresse angegeben?
  if(!ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,4})$",$_POST['email']))
  {
	$errmsg .= "Es wurde keine richtige Email-Adresse angegeben.<br />";
  }
  else
  {
    $maillink = "<a href=\"mailto:$wert\">";
  }
  
  // AntiSpam-Code richtig?
  if($_POST['captcha'] !== $_SESSION['captcha'])
  {
    $errmsg .= "Der AntiSpam-Code ist falsch.<br />";
  }
  session_destroy();

  
  foreach($_POST as $feld => $wert)
  {
    // Richtiger Name eingegeben?
	if($feld == "name")
	{
	  if(strlen($wert) < 3)
      {
        $errmsg .= "Es wurde kein richtiger Name eingegeben.<br />";
      }
	  else
	  {
	    $wert = $maillink.$wert."</a>";
      }
	}
	
	// Homepage angegeben?
	if($feld == "homepage")
	{
	  if(ereg("^([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,4})$",$wert))
	  {
        //Es wurde auch eine Homepageadresse angegeben - entsprechende Formatierung vornehmen
        if(!ereg("^http:////",$wert))
	    {
          //http:// fehlt in der Angabe der Adresse - hier ergaenzen
          $wert = "http://".$wert;
        }
        $wert = "<br>Homepage: <a href=\"" . $wert . "\" target=\"new\">" . $wert . "</a>";
      }
	}
	
	//Auch etwas geschrieben?
    if($feld == "eintrag")
	{
	  if(strlen($wert) < 5)
	  {
	    $errmsg .= "Es wurde kein Beitrag geschrieben.<br />";
	  }
	}
	
	if($feld == "submit")
    {
	  $wert = "";
	}
	
	//SQL-Kommando erstellen  
    $sql .=  "'".$wert."',";
  }
  
  $sql .= "'".date("Y-m-d H:i:s")."');";  
  if(strlen($errmsg) > 2)
  {
    echo $errmsg;
  }
  echo $sql;
}
else
{
?>
<link rel="stylesheet" href="../layout/style.css">
<center>
      <p align=center><b><u>Sprich dich aus!</u></b></p>
      
      <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <table width="400" border="0" cellspacing="1" cellpadding="0" class="news_tab">
        <tr> 
          <td width="146" align=right> 
            <p>Name:</p>          </td>
          <td width="254" valign="middle"> 
            <input type="text" name="name" size="35" style="border: 0px solid black;">          </td>
        </tr>
        <tr> 
          <td width="146" align=right> 
            <p>eMail-Adresse:</p>          </td>
          <td width="254" valign="middle"> 
            <input type="text" name="email" size="35" style="border: 0px solid black;">          </td>
        </tr>
        <tr> 
          <td width="146" align=right> 
            <p>Homepage:</p>          </td>
          <td width="254" valign="middle"> 
            <input type="text" name="homepage" size="35" style="border: 0px solid black;">          </td>
        </tr>
        <tr> 
          <td width="146" align=right>
            <p>Eintrag:</p>          </td>
          <td width="254" valign="middle"><textarea name="eintrag" rows="3" cols="30" style="border: 0px solid black;"></textarea></td>
        </tr>
        <tr> 
<tr>
<td valign="top">AntiSpam-Code</td>
<td>
<img src="../layout/captcha.php" width="170" height="60" border="0" ALT="AntiSpam-Code" /><br/>
<?php echo $_SESSION['captcha'];?>
</td>
</tr>
<tr>
<td>AntiSpam Code hier eintippen</td>
<td><input type="text" size="35" maxlength="5" name="captcha" style="border: 0px solid black;"></td>
</tr>
<tr>
          <td>&nbsp;          </td> 
            <td>
              <input type="submit" name="submit" value="Abschicken">          </td>
        </tr>
      </table>
      </form> 
<br>
$_SESSION['captcha'] = <?php echo $_SESSION['captcha'];?>
</center>
<?php
}
?>

Ich bin schon einige mögliche Fehlerquellen durchgegangen, komme nicht auf die Lösung.
Wäre nett, wenn mir jemand helfen könnte.

Grüße
Graffcon
 
Beim ersten Aufruf des Formulars wird noch keine Session-Variable im Formular ausgegeben, sie wurde anscheinend in der Captcha-Datei nicht richtig zugewiesen.
Zu diesem Zeitpunkt hat der Webbrowser die „captcha.php“ noch gar nicht angefordert, also existiert der Wert auch noch nicht.
 
Ja, aber die „captcha.php“-Datei wird erst nach der Ausgabe des Veriablenwerts angefordert (auch wenn die Reihenfolge im Quellcode anders ist). Die Sitzungsdaten werden auch nur am Anfang der Laufzeit des Skripts gelesen und am Ende der Laufzeit wieder geschrieben.
 

Neue Beiträge

Zurück