PHP Weiterleitung funktioniert nur auf bestimmten Servern!?

Nose

Lieutenant
Registriert
Dez. 2007
Beiträge
826
Hallo!

Ich nutze für das Kontakt-Formular mancher Webseiten ein "Formmailer-Skript".
Das funktioniert i.d.R. auch einwandfrei, allerdings hab ichs gerade mit einem Webspace zu tun wo dieses Skript NICHT so funktioniert wie es funktionieren soll. Das identische Skript funktioniert bei anderen Hostern einwandfrei und lief auch sehr lange bei einem anderen Hosting-Paket von 1&1 ohne Probleme. Daher muss es was mit der PHP(?) konfiguration des Servers zu tun haben wo dieses Skript nicht ordnungsgemäß funktioniert.

Hier erstmal das Skript:

PHP:
<?php
 
// ======= Konfiguration:
 
$mailTo = 'zieladresse@emailprovider.com';
$mailFrom = '"Angezeigter Absender" <absenderadresse@absenderurl.com>';
$mailSubject    = 'Betreff der EMail';
$returnPage = 'http://www.google.com/';
$returnErrorPage = 'http://www.bing.com/';
$mailText = "";
 
// ======= Text der Mail aus den Formularfeldern erstellen:
 
// Wenn Daten mit method="post" versendet wurden:
if(isset($_POST)) { 
   // alle Formularfelder der Reihe nach durchgehen:
   foreach($_POST as $name => $value) {
      // Wenn der Feldwert aus mehreren Werten besteht:
      // (z.B. <select multiple>)
      if(is_array($value)) {
          // "Feldname:" und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ":\n";
          // alle Werte des Feldes abarbeiten
          foreach($valueArray as $entry) {
             // Einrückungsleerzeichen, Wert und Zeilenumbruch 
             // dem Mailtext hinzufügen
             $mailText .= "   " . $value . "\n";
          } // ENDE: foreach
      } // ENDE: if  
      // Wenn der Feldwert ein einzelner Feldwert ist:
      else {
          // "Feldname:", Wert und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ": " . $value . "\n";
      } // ENDE: else
   } // ENDE: foreach
} // if
 
// ======= Korrekturen vor dem Mailversand 
 
// Wenn PHP "Magic Quotes" vor Apostrophzeichen einfügt:
 if(get_magic_quotes_gpc()) {
     // eventuell eingefügte Backslashes entfernen
     $mailtext = stripslashes($mailtext);
 }

 
// ======= Mailversand
 
// Mail versenden und Versanderfolg merken
$mailSent = @mail($mailTo, $mailSubject, $mailText, "From: ".$mailFrom);
 
// ======= Return-Seite an den Browser senden
 
// Wenn der Mailversand erfolgreich war:
if($mailSent == TRUE) {
   // Seite "Formular verarbeitet" senden:
   header("Location: " . $returnPage);
}
// Wenn die Mail nicht versendet werden konnte:
else {
   // Seite "Fehler aufgetreten" senden:
   header("Location: " . $returnErrorPage);
}
 
// ======= Ende
 
exit();
 
?>

Der Mail Versand funktioniert stets einwandfrei, was NICHT funktioniert ist die Weiterleitung (im obigen Fall auf google.com, aber natürlich käme da die "success-page" hin). Im genannten Fall bleibe ich einfach auf einer leeren Seite stehen und in der Adresszeile ist die URL von dem Formmailer-Skript zu lesen. Falls das also nicht über PHP-Einstellungen zu lösen ist käme für mich auch ein Workaround in Frage, wenn da jemand einen Vorschlag zu machen hat?

Wie gesagt, das selbe Skript hab ich auf anderen Webservern getestet, und in der Regel funktioniert es, aber bei manchen Hostern macht es Probleme.

Hat jemand ne Idee?

Vielen Dank schonmal! :)
 
Location ist ein header und funktioniert nur dann, wenn der Empfänger auch noch Kopfzeilen erwartet. Ich würde vermuten, daß da aus irgendeinem Grund vorher bereits irgendwelche Daten geschickt wurden. Es würde bereits ein einfaches Leerzeichen ausreichen.

BTW, bist du dir sicher, daß der Mailversand problemlos verläuft? Eine mögliche Fehlermeldung wird von dir ja ignoriert...
 
der mailversand funktioniert völlig problemlos und zuverlässig, ja.

aber mit dem rest von deiner antwort kann ich leider nix anfangen, da ich mich mit php null auskenne. weiters ist es mir schleierhaft warum es beim einen server funktioniert und beim anderen nicht, da wie gesagt die EXAKT selben dateien verwendet wurden!?

Hier mal der Code vom Formular, wenn der weiterhilft?

HTML:
<form name="contact" method="post" action="form-mailer.php">
<label>Ihre Email-Adresse:<input type="email" name="email" required></label>
<label style="">Ihr Name:<input type="text" name="name" required></label>
<label>Ihre Nachricht an mich:<textarea class="area2" name="nachr" required>
</textarea></label><input type="submit" class="button" value="Nachricht senden">
</form>


danke! :)
Ergänzung ()

aha, php ist ein haarspalter wie ihn die welt noch nicht gesehen hat. es war zwar kein leerzeichen irgendwo, nein, es war das Byte-Order-Mark was mir den Strich durch die Rechnung gemacht hat.

Ziemlich pingelig, dieses PHP. :freak:
 
Zuletzt bearbeitet:
Habe das Formular ein wenig modifiziert.

Ist es gewollt, dass man auf eine extra Seite weitergeleitet wird?
Warum nicht alles in einer einzigen PHP-Seite realisieren?

Meine Modifizierung macht genau das:

PHP:
if (isset( $_POST['form1'] ))
<- erst wenn das Formular mit dem Submit-Button "form1" per POST "erkannt" wird, werden die nachfolgenden PHP-Befehle ausgeführt (bzw. die Mail versendet).

Code:
if($mailSent == TRUE) {   // Seite "Formular verarbeitet" senden:
   echo 'Die Mail wurde erfolgreich versendet!';
   header('refresh: 7'); //Lädt das Formular nach 7 Sekunden neu
}
<- wurde die Mail erfolgreich versendet, wird dies per "echo" auf den Bildschirm ausgegeben. Nach 7 Sekunden wird das Formular neu geladen.

Achtung: "header"-Weiterleitungen könnten in Firefox, je nach Browsereinstellung, eine Warnung ausgeben und das Neuladen oder eine Weiterleitung verhindern! Diese Meldung kann man leicht übersehen! Deshalb empfehle ich vor allem bei PHP-Mailer, keine extra PHP-Seite zu erstellen welche sich explizit um die Abarbeitung des Mailversands und der Weiterleitung kümmert. Sonst kann es passieren, dass die Nutzer nur noch eine weiße Seite vor sich haben, weil die Weiterleitung geblockt wird. Außerdem sieht das nicht so dolle gut aus wenn man extra weitergeleitet wird :)

Komplette modifizierte PHP inkl. Formular:

Code:
<?php
if (isset( $_POST['form1'] )) //Mail wird nur versendet, wenn ein POST von einem Formular mit dem Submit-Button "form1" eingeht
{ 
// ======= Konfiguration:
 
$mailTo = 'mail@mail.mail';
$mailFrom = '"Angezeigter Absender" <absenderadresse@absenderurl.com>';
$mailSubject    = 'Betreff der EMail';
//$returnPage = 'http://www.google.com/';
//$returnErrorPage = 'http://www.bing.com/';
$mailText = "";
 
// ======= Text der Mail aus den Formularfeldern erstellen:
 
// Wenn Daten mit method="post" versendet wurden:


   // alle Formularfelder der Reihe nach durchgehen:
   foreach($_POST as $name => $value) {
      // Wenn der Feldwert aus mehreren Werten besteht:
      // (z.B. <select multiple>)
      if(is_array($value)) {
          // "Feldname:" und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ":\n";
          // alle Werte des Feldes abarbeiten
          foreach($valueArray as $entry) {
             // Einrückungsleerzeichen, Wert und Zeilenumbruch 
             // dem Mailtext hinzufügen
             $mailText .= "   " . $value . "\n";
          } // ENDE: foreach
      } // ENDE: if  
      // Wenn der Feldwert ein einzelner Feldwert ist:
      else {
          // "Feldname:", Wert und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ": " . $value . "\n";
      } // ENDE: else
   } // ENDE: foreach
 // if
 
// ======= Korrekturen vor dem Mailversand 
 
// Wenn PHP "Magic Quotes" vor Apostrophzeichen einfügt:
 if(get_magic_quotes_gpc()) {
     // eventuell eingefügte Backslashes entfernen
     $mailtext = stripslashes($mailtext);
 }
 
 
// ======= Mailversand
 
// Mail versenden und Versanderfolg merken
$mailSent = @mail($mailTo, $mailSubject, $mailText, "From: ".$mailFrom);
 
// ======= Return-Seite an den Browser senden
 
// Wenn der Mailversand erfolgreich war:
if($mailSent == TRUE) {
   // Seite "Formular verarbeitet" senden:
   echo '<font size="+2" color="green">Die Mail wurde erfolgreich versendet!</font>'; //weiteres HTML kann hier eingetragen werden
   header('refresh: 7'); //Lädt das Formular nach 7 Sekunden neu
}
// Wenn die Mail nicht versendet werden konnte:
else {
   // Seite "Fehler aufgetreten" senden:
   echo 'Fehler beim Mailversand!<br>Bitte erneut versuchen!';
   header('refresh: 5');
}
 
// ======= Ende


exit();
}; //if isset wird geschlossen
?>
<form name="contact" method="post" action="#">
<label>Ihre Email-Adresse:<input type="email" name="email" required></label>
<label style="">Ihr Name:<input type="text" name="name" required></label>
<label>Ihre Nachricht an mich:<textarea class="area2" name="nachr" required>
</textarea></label><input type="submit" name="form1" class="button" value="Nachricht senden">
</form>
 
Zuletzt bearbeitet:
aha, das sieht doch ganz interessant aus!

vielen dank, ich werd mir das morgen, bzw später mal genauer anschauen!

zur frage ob das gewollt ist dass man auf eine extra seite weitergeleitet wird...ja und nein. zum einen finde ich es als user recht angenehm wenn man merkt "aha, da kommt jetzt ne neue seite die mir bestätigt dass die mail verschickt wurde". klar, das ließe sich auch etwas eleganter lösen, aber ich erstell die ganzen webseiten nur hobbymäßig und da wars mir genug aufwand überhaupt erstmal ein freies und funktionierendes formmailer-skript zu finden. mich da dann weitgenug in php einzuarbeiten als dass ich das umschreibe so dass es etwas schicker wird, das war mir dann doch zu viel aufwand.

aber ich werd mir das was du gemacht hast mal anschauen und wenns das ist was ich glaube dass es ist in meine seiten integrieren! danke! :)
Ergänzung ()

masterrob schrieb:
Achtung: "header"-Weiterleitungen könnten in Firefox, je nach Browsereinstellung, eine Warnung ausgeben und das Neuladen oder eine Weiterleitung verhindern! Diese Meldung kann man leicht übersehen! Deshalb empfehle ich vor allem bei PHP-Mailer, keine extra PHP-Seite zu erstellen welche sich explizit um die Abarbeitung des Mailversands und der Weiterleitung kümmert. Sonst kann es passieren, dass die Nutzer nur noch eine weiße Seite vor sich haben, weil die Weiterleitung geblockt wird. Außerdem sieht das nicht so dolle gut aus wenn man extra weitergeleitet wird :)

da muss ich jetzt noch nachfragen...ich dachte die php geschichte wird komplett serverseitig abgehandelt und der browser bekommt dann einfach nur das ergebnis (in dem fall die weiterleitung zur success/fail-page) mit!?
 
Nose schrieb:
da muss ich jetzt noch nachfragen...ich dachte die php geschichte wird komplett serverseitig abgehandelt und der browser bekommt dann einfach nur das ergebnis (in dem fall die weiterleitung zur success/fail-page) mit!?

Das ist soweit korrekt.
Vielleicht interpretierst Du auch gerade etwas zu viel in meine Ausführung ;)
Sobald Du das HTML-Formular absendest, werden in meinem Beispiel auf der gleichen Seite die PHP-Befehle abgearbeitet und die Mail versendet - eine Bestätigung bei Erfolg wird ausgegeben. Danach (auch in meinem Beispiel) wird das Formular nach 7 Sekunden neu geladen, bzw. die Seite wird neu geladen. Genau da hakt es gerne beim Firefox. Da es im Firefox eine Einstellung gibt, die einen warnt sobald eine Webseite versucht weiterzuleiten oder die Seite neu zu laden. Das gleiche Prinzip gilt dann auch bei Weiterleitungen.

Ist im Grunde nur eine Schönheitsgeschichte - sieht professioneller aus. Kann sonst passieren, dass Firefox-Nutzer nur noch eine weiße Seite vor sich haben und nicht weitergeleitet werden, da Firefox dies verhindert. Bei meinem Beispiel wird dann zwar das Formular bei paranoiden Firefox-Nutzern dann auch nicht neu geladen, aber immerhin ist eine Bestätigung da und die Benutzer sind immer noch mitten auf Deiner Webseite.

Probier es einfach mal aus. Pack den kompletten Quellcode einfach irgendwo in Deine Webseite.

P.S.: Es ist in der Tat immer empfehlenswert die "if isset" Anweisung auf ein bestimmtes Formular zu spezifizieren. So ist es auch möglich mehrere Formulare (wie z.B. Logins, Suche, Formular-gebundene SQL-Querys, ...) auf einer einzigen Seite zur Verfügung zu stellen.

Probier es aus:
Code:
<?phpif (isset( $_POST['form1'] )) //Mail wird nur versendet, wenn ein POST von einem Formular mit dem Submit-Button "form1" eingeht
{ 
// ======= Konfiguration:
 
$mailTo = 'mail@mail.mail';
$mailFrom = '"Angezeigter Absender" <absenderadresse@absenderurl.com>';
$mailSubject    = 'Betreff der EMail';
//$returnPage = 'http://www.google.com/';
//$returnErrorPage = 'http://www.bing.com/';
$mailText = "";
 
// ======= Text der Mail aus den Formularfeldern erstellen:
 
// Wenn Daten mit method="post" versendet wurden:
 
 
   // alle Formularfelder der Reihe nach durchgehen:
   foreach($_POST as $name => $value) {
      // Wenn der Feldwert aus mehreren Werten besteht:
      // (z.B. <select multiple>)
      if(is_array($value)) {
          // "Feldname:" und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ":\n";
          // alle Werte des Feldes abarbeiten
          foreach($valueArray as $entry) {
             // Einrückungsleerzeichen, Wert und Zeilenumbruch 
             // dem Mailtext hinzufügen
             $mailText .= "   " . $value . "\n";
          } // ENDE: foreach
      } // ENDE: if  
      // Wenn der Feldwert ein einzelner Feldwert ist:
      else {
          // "Feldname:", Wert und Zeilenumbruch dem Mailtext hinzufügen
          $mailText .= $name . ": " . $value . "\n";
      } // ENDE: else
   } // ENDE: foreach
 // if
 
// ======= Korrekturen vor dem Mailversand 
 
// Wenn PHP "Magic Quotes" vor Apostrophzeichen einfügt:
 if(get_magic_quotes_gpc()) {
     // eventuell eingefügte Backslashes entfernen
     $mailtext = stripslashes($mailtext);
 }
 
 
// ======= Mailversand
 
// Mail versenden und Versanderfolg merken
$mailSent = @mail($mailTo, $mailSubject, $mailText, "From: ".$mailFrom);
 
// ======= Return-Seite an den Browser senden
 
// Wenn der Mailversand erfolgreich war:
if($mailSent == TRUE) {
   // Seite "Formular verarbeitet" senden:
   echo '<font size="+2" color="green">Die Mail wurde erfolgreich an die Technik versendet!</font>'; //weiteres HTML kann hier eingetragen werden
   header('refresh: 7'); //Lädt das Formular nach 7 Sekunden neu
}
// Wenn die Mail nicht versendet werden konnte:
else {
   // Seite "Fehler aufgetreten" senden:
   echo 'Fehler beim Mailversand!<br>Bitte erneut versuchen!';
   header('refresh: 5');
}
 
// ======= Ende
 
 
exit();
};
?>
<?php
if (isset( $_POST['form2'] )) //Wird nur ausgeführt wenn ein POST von einem Formular mit dem Submit-Button "form2" eingeht
{ 
 $_POST = get_magic_quotes_gpc() ? array_map( 'stripslashes', $_POST ) : $_POST;




echo 'Hallo ' . $_POST['name'] . ' mit der E-Mail Adresse ' . $_POST['email'] . '.<br>Deine Nachricht lautet: ' . $_POST['nachr'] . '.';
exit();
};
?>
<form name="contact" method="post" action="#">
<label>Ihre Email-Adresse:<input type="email" name="email" required></label>
<label style="">Ihr Name:<input type="text" name="name" required></label>
<label>Ihre Nachricht an mich:<textarea class="area2" name="nachr" required>
</textarea></label><input type="submit" name="form1" class="button" value="Mail senden">
<input type="submit" name="form2" class="button" value="POST anzeigen">
</form>


 
Zuletzt bearbeitet:
Wieso überhaupt ein Header redirect? Wie wahrscheinlich ist es das jemand eine Mail via Formular versendet und dann direkt noch mal das Formular verwenden will?

Form anzeigen, auf POST warten und wenn Mail erfolgreich versendet ne Erfolgsmeldung und fertig!
 
Nose schrieb:
Ergänzung ()

aha, php ist ein haarspalter wie ihn die welt noch nicht gesehen hat. es war zwar kein leerzeichen irgendwo, nein, es war das Byte-Order-Mark was mir den Strich durch die Rechnung gemacht hat.

Ziemlich pingelig, dieses PHP. :freak:

Das ist KEIN Fehler (oder Pingeligkeit) seitens PHP, sondern vollkommen korrektes Verhalten. Header müssen immer als allererstes übertragen werden. Kein Krümel Datenstrom darfs ich vor den Headern befinden. Ein BOM ist aber ein Stück Datenstrom, und zwar ein vollkommen nutzloses.

Daher für die Zukunft:
- Programmier in Editoren, die explizit ohne BOM speichern
- verwende, soweit möglich, den PHP Output Buffer. Das vermeidet viele Header-Fehler und vereinfacht den Code langfristig.

Bisumaruku schrieb:
Wieso überhaupt ein Header redirect? Wie wahrscheinlich ist es das jemand eine Mail via Formular versendet und dann direkt noch mal das Formular verwenden will?
Tatsächlich... sehr wahrscheinlich. F5-Spam oder wildes Geklicke auf die Zurück-Taste sind doch sehr beliebt.

Nach POSTs ist es ratsam, einen 303 "See other" durchzuführen, damit sämtliche POST-Überreste entsorgt werden und es nicht zu Doppel-Versand kommen kann.
 
Nose schrieb:
aha, php ist ein haarspalter wie ihn die welt noch nicht gesehen hat. es war zwar kein leerzeichen irgendwo, nein, es war das Byte-Order-Mark was mir den Strich durch die Rechnung gemacht hat.

Ziemlich pingelig, dieses PHP. :freak:

Da ist nicht PHP pingelig, sondern alles andere außer PHP, nämlich der Webserver und HTTP. Das BOM steht in der Datei *vor* dem "<?php". Es wird also ausgegeben, bevor PHP überhaupt mit der Ausführung beginnt. Über diese Stellen hat PHP keine Kontrolle. Zu dem Zeitpunkt, wo dann das "header()" kommt, kann PHP nur noch mitteilen, dass leider keine Header mehr gesetzt werden können, weil die Ausgabe schon begonnen hat.

Im Übrigen wundere ich mich, warum keiner auf den Fehler im Skript hinsichtlich Array-Werten hingewiesen hat. Die Variable "$valueArray" in Zeile 24 gibt es nicht, es muss nur "$value" heißen. Außerdem ist das Skript so aufgebaut, dass bei leeren POST-Daten dennoch eine leere Mail verschickt wird; das dürfte so auch nicht erwünscht sein.

Und zu den Empfehlungen unten: Irgendeine Weiterleitung ist nach einem POST-Request immer Pflicht, damit man die POST-Daten entsorgt, wie Daaron es schon gesagt hat.
 
Zurück
Oben