• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Problem mit Button

freakXHTML

Mitglied
Hallo zusammen,
ich habe ein Formular und gleich darunter den PHP Code, der dieses ausliest. Der Code soll natürlich nur ausgeführt werden, wenn der Submitknopf gedrückt worden ist. Dazu habe ich zdrei Fragen.

PHP:
 <form action="" method="post">
  <fieldset>
    //...
    <input style="display:block; " class="inputbox" type="text" name="Vorname" />
    <input id="resfeed" type="submit" name="send"  class="buttonfeedback" value="Abschicken" />
  </fieldset>
 </form> 
 <?php 
 if(isset($_POST['send']) && isset($_POST['Vorname']))
   echo "Bitte f&uuml;llen Sie alle Felder aus!";
 
 ?>

1.) Sobald ich den Submitbutton drücke, erfolgt die Ausgabe "Bitte füllen Sie alle Felder aus!". Auch wenn ich das Feld ausgefüllt habe, kommt diese Fehlermeldung. Ich habe mal isset($_POST['Vorname']) ausgebenen und die Ausgabe ist stets 1. Warum?



2.) Wenn der Submitknopf gedrückt wurde, dann sollte die Ausgabe erfolgen. Wenn nun die Seite aktualisiert wird, dann soll diese jedoch wieder weg sein, denn sonst würde das Formular ja zweimal abgeschickt. Wie kann ich das machen?

3.) Ich möchte, dass die PHP Ausgabe über dem Submitbutton geschieht. Wie mache ich das, denn der eigentliche Code kann ja erst nach dem Formular kommen?!

Vielen Dank
lg, freakXHTML
 
Zuletzt bearbeitet:
hi
also ich habe zwar nich auf alle deine fragen ne antwort aba auf einpaar:

1.) du musst
HTML:
<form action="NameDesDokuments.html" method="post">
...
schreiben damit das formular "weiss" wo es die informationen hinschicken soll

das 2. weiss ich nich so genau...und beim 3. kannste nich den php-code vor das formular setzen?

hoffe ich konnte helfen
mfg michaelos
 
Zu 1: In Worte gefasst besagt deine Bedingung: "Wenn Feld 'send' gesetzt ist und Feld 'Vorname' gesetzt ist, dann..." Du suchst vermutlich das genaue Gegenteil: "Wenn Feld 'send' NICHT gesetzt ist ODER Feld 'Vorname' NICHT gesetzt ist, dann..." (Für extra Geek-Punkte: De Morgansche Gesetze)

Zu 2: Das doppelte Absenden kannst du zum Beispiel durch eine header()-Weiterleitung an dieselbe URL nach Auswertung des Formulars verhindern (dadurch werden die POST-Daten gelöscht).

PHP:
// ...
header('Location: http://example.org/url-der-seite.php');
exit;

- PHP: header - Manual

Das Problem ist, dass es auf diese Weise schwierig ist, eine Bestätigung für die durchgeführte Formularaktion auszugeben. Dazu vielleicht später mehr.

Zu 3: Vergegenwärtige dir die Ablauflogik. Es handelt sich beim ersten Anzeigen des Formulars und beim Abschicken/Auswerten um zwei Requests. Pseudocode:

Code:
if (formularAbgeschickt):
    WerteFormularAus;
    GebeNachrichtAusOderMacheHeaderRedirect;
else:
    ZeigeFormularAn;
endif;

Da beim ersten Aufruf der Seite "formularAbgeschickt" nicht wahr ist (lässt sich über den Gesetzt-Status der POST-Felder ermitteln), wird die else-Bedingung ausgeführt. Beim Abschicken des Formulars (zweiter Aufruf) ist "formularAbgeschickt" dann wahr, sodass der erste Zweig der if-Bedingung durchlaufen wird.
 
2.) Trenn erstmal das php vom html code. zB so:

formular.htm:

HTML:
<form action="name.php" method="post">
  <fieldset>
 
    <input style="display:block; " class="inputbox" type="text" name="Vorname" />
   <input id="resfeed" type="submit" name="send"  class="buttonfeedback" value="Abschicken" />
  </fieldset>
 </form>

und dann noch die Datei -> name.php:
PHP:
<?php 
 if(!$_POST['vorname'] || $_POST['vorname'] == "") {
header('Location: formular.htm');
}
else
{ 
header('Location: formular.htm');
?>



Du kannst jetzt noch ne Variable setzen zB: $falsch = 'Bitte alle Felder ausfüllen';

Die Variable gibts du an der gewünschten Stelle im formular.htm aus, also so:

echo "$falsch"


Und wenn alles richtig gemacht wurde, machst das selbe wie beim obrigen beispiel, also zB: $richtig = 'Du hast alle Felder korrekt ausgefüllt'
 
T!P-TOP schrieb:
Du kannst jetzt noch ne Variable setzen zB: $falsch = 'Bitte alle Felder ausfüllen';

Die Variable gibts du an der gewünschten Stelle im formular.htm aus, also so:

echo "$falsch"

Das klappt nicht. Die Variablen gehen durch die Header-Weiterleitung verloren.

Ich würde hier auch keine zwei Dateien erstellen, sondern alles in eine setzen.

Hier ein Beispiel:

PHP:
<?php

$errors      = array();
$isSubmitted = false;

if (isset($_POST['form_id']) && ($_POST['form_id'] === 'demo')) {
    $isSubmitted = true;

    $_POST['vorname'] = (isset($_POST['vorname'])) ? trim($_POST['vorname']) : '';

    if ($_POST['vorname'] === '') {
        $errors[] = 'Feld vorname nicht gesetzt';
    }

    if (empty($errors)) {
        // Daten irgendwie verarbeiten, falls keine Fehler aufgetreten sind
        // ...
    }

    // header-Weiterleitung
    if (empty($errors)) {
        header('Location: http://' . $_SERVER['SERVER_NAME']
                                   . $_SERVER['SCRIPT_NAME']);
        exit;
    }
}

?>

<?php if ($isSubmitted): ?>

    <?php if (empty($errors)): ?>

        <p>Formular erfolgreich abgeschickt</p>

        <!-- Dieser Zweig wird bei der vorliegenden header-Weiterleitung
             nicht ausgelöst. -->

    <?php else: ?>

        <p>Folgende Fehler sind aufgetreten:</p>

        <ul>
        <?php foreach ($errors as $error): ?>
            <li><?php echo htmlspecialchars($error); ?></li>
        <?php endforeach; ?>
        </ul>

    <?php endif; ?>

<?php endif; ?>

<form action="" method="post">
  <fieldset>
    <input type="text" name="vorname" />
    <input type="hidden" name="form_id" value="demo" />
    <input type="submit" name="send" value="Abschicken" />
  </fieldset>
</form>

Das Problem besteht wie gesagt darin, eine Erfolgsmeldung auszugeben und gleichzeitig eine header-Weiterleitung (wegen doppelt abgeschickter POST-Daten) zu implementieren.
 
mal ein tipp nebenbei, diesen ganzen &auml; scheiß kannst du vergessen, speicher das Dokument lieber im richtigen Encoding :)
 
Er kann die Variablen in einer Session weitergeben!?

Ja, zum Beispiel. Aber da wird's meines Erachtens langsam schwierig, ein halbwegs elegantes Beispiel zu erstellen, ohne auf größere Mengen an Infrastrukturcode zurückzugreifen. (Projektbezogene Session-Daten sollten immer in einem Namespace stehen, um Namenskonflikte zu vermeiden. Dazu braucht es dann im Prinzip bereits eine Art Container-Klasse für das Session-Management.)

Irgendwie so zum Beispiel. (Nicht wirklich getestet, bei deaktivierten Cookies gibt es keine Nachrichten.)

index.php

PHP:
<?php

error_reporting(-1);

require_once './Session_Container.php';

session_start();

$sc = new Session_Container('myproject');

$errors      = array();
$isSubmitted = false;
$success     = ($sc->pop('forms.demo') === 'success');

if (isset($_POST['form_id']) && ($_POST['form_id'] === 'demo')) {
    $isSubmitted = true;

    $_POST['vorname'] = (isset($_POST['vorname'])) ? trim($_POST['vorname']) : '';

    if ($_POST['vorname'] === '') {
        $errors[] = 'Feld vorname nicht gesetzt';
    }

    if (empty($errors)) {
        // Daten irgendwie verarbeiten, falls keine Fehler aufgetreten sind
        // ...
    }

    // header-Weiterleitung
    if (empty($errors)) {
        $sc->set('forms.demo', 'success');

        header('Location: http://' . $_SERVER['SERVER_NAME']
                                   . $_SERVER['SCRIPT_NAME']);
        exit;
    }
}

?>

<?php if ($isSubmitted): ?>

    <?php if (!empty($errors)): ?>

        <p>Folgende Fehler sind aufgetreten:</p>

        <ul>
        <?php foreach ($errors as $error): ?>
            <li><?php echo htmlspecialchars($error); ?></li>
        <?php endforeach; ?>
        </ul>

    <?php endif; ?>

<?php endif; ?>

<?php if ($success): ?>

    <p>Formular erfolgreich abgeschickt</p>

<?php endif; ?>

<form action="" method="post">
  <fieldset>
    <input type="text" name="vorname" />
    <input type="hidden" name="form_id" value="demo" />
    <input type="submit" name="send" value="Abschicken" />
  </fieldset>
</form>

<hr />
<p>Debug</p>

<pre>
<?php print_r($_SESSION); ?>
</pre>

Session_Container.php

PHP:
<?php

/**
 * A container class for interfacing with session data using a namespace
 *
 * Usage example:
 *
 * <code>
 * session_start();
 * $sc = new Session_Container('myproject);
 *
 * $sc->set('core.user.id', $userId);
 *     // Meaning: $_SESSION[<namespace>]['core']['user']['id'] = $userId;
 *
 * $userId = $sc->get('core.user.id');
 *     // $userId = $_SESSION[<namespace>]['core']['user']['id'];
 *
 * // And so on...
 * </code>
 *
 * @todo This class isn't thoroughly tested
 * @author Marc Ermshaus <[email protected]>
 * @version 2010-07-12
 */
class Session_Container
{
    /**
     * @var string This container's namespace
     */
    protected $_namespace = '';

    /**
     * Creates a new container
     *
     * @param string $namespace Namespace in $_SESSION for this container
     */
    public function __construct($namespace = 'default')
    {
        $this->_namespace = $namespace;
    }

    /**
     * Returns a reference to the element in $_SESSION denoted by $keyParts
     *
     * @param array $keyParts
     * @throws Exception Element not found
     * @return mixed
     */
    protected function &_resolveKey(array $keyParts)
    {
        $parent = &$_SESSION[$this->_namespace];

        foreach ($keyParts as $part) {
            if (isset($parent[$part])) {
                $parent = &$parent[$part];
            } else {
                throw new Exception();
            }
        }

        return $parent;
    }

    /**
     * Set a key's value
     *
     * @param string $key
     * @param mixed $value
     */
    public function set($key, $value)
    {
        $keyParts = explode('.', $key);
        $leaveKey = array_pop($keyParts);

        $parent = &$_SESSION[$this->_namespace];

        foreach ($keyParts as $part) {
            if (!isset($parent[$part])) {
                $parent[$part] = array();
            }

            $parent = &$parent[$part];
        }

        $parent[$leaveKey] = $value;
    }

    /**
     * Get a key's value
     *
     * @param string $key
     * @return mixed
     */
    public function get($key)
    {
        $keyParts = explode('.', $key);

        try {
            $parent = $this->_resolveKey($keyParts);
        } catch (Exception $e) {
            $parent = null;
        }

        return $parent;
    }

    /**
     * Delete a key
     *
     * @param string $key
     * @return bool
     */
    public function delete($key)
    {
        $keyParts = explode('.', $key);
        $leaveKey = array_pop($keyParts);

        try {
            $parent = &$this->_resolveKey($keyParts);
        } catch (Exception $e) {
            return false;
        }

        unset($parent[$leaveKey]);
        return true;
    }

    /**
     * Get and delete a key
     *
     * @param string $key
     * @return mixed
     */
    public function pop($key)
    {
        $value = $this->get($key);
        $this->delete($key);
        return $value;
    }
}
 
Hallo,

auch wenn Du ein leeres Formular abschickst, sind die $_POST[] Variablen gesetzt, nur halt leer. Die isset() Funktion fragt nur ab, ob die Variable da ist und liefert true(1) oder false(0) zurück. Um rauszufinden ob die Variable auch gefüllt ist, solltest Du mit empty() bzw. !empty() arbeiten.

Gruß
/martin
 
Sie sind aber nicht gesetzt, wenn jemand das Formular manipuliert und das Feld entfernt hat.

Der Hinweis mit empty() ist gut, wobei ich persönlich an der Funktion nicht mag, dass auch (string) "0" als empty angesehen wird. (Das mag selten von Belang sein, aber "0" ist nunmal häufig formal betrachtet keine fehlerhafte Eingabe. Im Grunde müsste man das berücksichtigen.)

Ich mache deshalb in simplen Scripts meist sowas (siehe auch oben), um sicherzustellen, dass alle erwarteten Werte zumindest gesetzt sind:

PHP:
$_POST['vorname'] = (isset($_POST['vorname'])) ? trim($_POST['vorname']) : '';

Die Validierung würde dann entsprechend den Default-Wert (hier: '' (leerer String)) als fehlerhafte Eingabe erkennen.

Eigentlich müsste noch ein Test auf is_array() dabei stehen, falls irgendein Schlaumeier ein POST-Feld zu einem Array umgebaut hat[1]. Ist ein wenig indifferent. ;)

Wo wir jetzt schon so sehr in die Details gehen: Es gibt sehr mächtige OOP-Lösungen zur Erstellung und Validierung von Formularen. Zum Beispiel aus dem Zend Framework.

- Zend Framework: Documentation: Zend_Form Quick Start - Zend Framework Manual



1: Hier würde wiederum empty() helfen.

PHP:
<?php

error_reporting(-1);

$_POST['test'] = array();

if (trim($_POST['test']) !== '') {
    echo 'Hups, das sollte nicht passieren';
}
 
Zuletzt bearbeitet:
das ändert nichts an der Tatsache, das $_POST[] immer gesetzt ist ... und auch immer "true" oder "1" zurück liefern wird. Auch wenn der Wert "null" ist
 
Ich nehme an, du meinst Felder in $_POST und nicht das $_POST-Array selbst?

PHP:
<?php

var_dump(isset($_POST['test']));

// bool(false)
 
Zurück
Oben