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

Problem mit true

freakXHTML

Mitglied
Hallo zusammen,
ich habe eine Funktion, die eine Eingabe prüft. Bei Fehler gibt sie immer die entsprechenden Strings zurück. Also:

PHP:
if(...) return "Du hast keine Nachricht eingegeben.";
elseif(...) return "Du musst eine E - Mail Adresse eingeben.";

Nur wenn die Eingabe erfolgreich war, wird true zurückgegeben.

PHP:
if(eingabewarerfolgreich) return true;

In einer anderen Datei speichere in den return Wert in einer Variablen. Nun möchte ich diese abfragen. Die Variable heißt $feedback. Ich dachte, dass ich einfach prüfe, ob sie true ist und dann fortfahren kann, denn dann war die Eingabe korrekt. Mein Code dazu sieht so aus:

PHP:
if($feedback == true) machweiter();

Mein Problem ist, dass die obige Fallunterscheidung immer true ist. Wenn $feedack einen String wie "Du hast keine Nachricht eingegeben" enthält, dann ist if dennoch true. Warum? Wie kann ich den Bug beheben?

Vielen Dank
lg, freakXHTML
 
TRUE und FALSE sind nicht dein Ding oder :mrgreen:
Mal ein anderer Ansatz, der für Dich vielleicht einfacher zu verstehen ist und leicht zu erweitern wäre.
PHP:
function check_zeugs($mail,$post)
{
 $error = "";
 if($mail == ""))
 {
  $error = 'keine Mailadresse';
  }

  if($post == "")
  {
   $error = 'keine Nachricht';
  }
  return $error;
}

// eingabe pruefen
$fehler = check_zeugs($_POST['mail'],$_POST['nachricht']);

// Rueckmeldung weiter verarbeiten
if($fehler == "") // kein fehler vorhanden
{
  // senden, speichern, was auch immer...
}
else
{
  echo $fehler;
}
Boolsche Werte können von so vielen Dingen beeinflusst werden, dass ich sowas niemals mit TRUE oder FALSE prüfen würde.
Funktionsaufrufe, Ausdrücke etc können FALSE liefern, wenn sie z.B. nicht korrekt definiert wurden oder fehlende Parameter den Aufruf unmöglich machen, und und und..

ps
Du speicherst die Rückgabe in $feedback, somit ist sie immer TRUE.
 
Zuletzt bearbeitet von einem Moderator:
Es ist darüber hinaus allgemein kein guter Stil, eine Funktion/Methode verschiedene Datentypen zurückgeben zu lassen. Manche Standardfunktionen von PHP tun das, aber eigener Code sollte darauf nach Möglichkeit verzichten. Wenn du eine Funktion/Methode, die eigentlich einen Wert liefern sollte, mit einem Fehler abbrechen möchtest, kannst du etwa auch Exceptions nutzen. (Oder wie in sysops Beispiel den leeren String oder ein leeres Array als "kein Fehler" definieren.)

- PHP: Exceptions - Manual

PHP ist schwach (loose) typisiert, jede Variable besitzt aber dennoch intern einen Datentyp. PHP verfügt deshalb über Möglichkeiten, Werte "loose" (ohne Berücksichtigung des internen Datentyps) oder "strict" (mit Berücksichtigung) zu vergleichen.

- PHP: PHP type comparison tables - Manual

Wenn du sichergehen willst, dass ein Wert tatsächlich (bool) true ist und nicht etwa (string) "hallo", nutze striktes Vergleichen ("==="-Operator, siehe teeny). (Meiner Meinung nach spricht wenig dagegen, nahezu immer strikt zu vergleichen, aber völlig konsequent praktiziere ich das auch nicht.)

Da PHP kein Type-Hinting für primitive Datentypen (int, string, bool, ...) unterstützt, können Primitive als Funktionsparameter zu Beginn des Funktionskörpers explizit typegecastet werden:

PHP:
/**
 * Beispielfunktion
 *
 * @param int    $i
 * @param string $y
 * @param bool   $b
 */
function f($i, $s, $b)
{
    $i = (int)    $i;
    $s = (string) $s;
    $b = (bool)   $b;

    // Funktionskörper
    var_dump($i, $s, $b);        
}

f('Hallo', 123, 'Welt');
    // int(0) string(2) "23" bool(true)

Ob das übertrieben ist oder ob es dann übertrieben ist, zusätzlich noch strikte Vergleiche zu nutzen, lasse ich dahingestellt. Auch wenn PHP eine schwach typisierte Sprache ist, gehört es für mich jedenfalls zum sauberen Programmieren, den internen Datentyp einer Variable immer zu berücksichtigen und im Zweifel selbst zu casten, statt auf PHPs automatische Typenumwandlung zu setzen.
 
Jep, sehe ich genauso.

Boolsche Werte übergebe ich so gut wie nie. Prüfungen haben für mich immer eine direkte Konsequenz.

PHP:
$janein = 0; // true_fase setzen 1=ja, 0=nein

if(file_exists($file)) 
{
  mach_was(); // auch wenn ich auf TRUE testen könnte
  $janein = 1;
}
else
{
  // wenn FALSE tue was anderes
  $janein = 0;
}

if(isset($wert))
{
  // gäbe, wenn gesetzt, TRUE zurück, aber wozu extra abfragen...
  gesetzt();
  $janein = 1;
}
else
{
  setze_wert();
  $janein = 0;
}


if(stristr(...)
{
  fuehre_etwas_aus(); // gross/kleinschreibung egal
  $janein = 1;
}
else
{
  // würde FALSE zurueck geben, wozu nochmal testen ??
  $janein = 0;
}

$janein könnte man nun dazu verwenden, um per $_GET oder $_POST das Ergebnis der Prüfung zu übergeben und man könnte eine entsprechende Ausgabe erzeugen, ohne Gefahr zu laufen Boolsche Werte zu verändern.

PHP:
if($janein == 1) echo "Prüfung ergab TRUE";
else echo "Prüfung ergab FALSE";
 
Ich hätte für sowas einen kleinen Auszug aus meiner Klasse:
PHP:
<?php
class validation {
	var $error_style = array ();
	var $error = false;
	function email ($adresse) {
		if (preg_match ('/^[_a-zA-Z0-9-](.{0,1}[_a-zA-Z0-9-])*@([a-zA-Z0-9-]{2,}.){0,}[a-zA-Z0-9-]{3,}(.[a-zA-Z]{2,4}){1,2}$/', $adresse)) {
			return true;
		} else {
			$this -> add_error ('email');
			return false;
		}
	}
	function username ($name) {
		if (preg_match ('/^[a-zA-Z0-9_\-]{4,15}$/', $name)) {
			return true;
		} else {
			$this -> add_error ('username');
			return false;
		}
	}

	function password ($password1, $password2) {
		if (strlen ($password1) >= 5 && strlen ($password1) <= 30 && $password1 == $password2) {
			return true;
		} else {
			$this -> add_error ('password');
			return false;
		}
	}
	function add_error ($type) {
		$this -> error = true;
		$this -> error_style[$type] = ' class="error"';
	}
	function return_error_style () {
		return $this -> error_style;
	}
}
?>

Dann kannst du alles einfach prüfen:
PHP:
$validate = new validation ();
if (isset ($_POST['absenden'])) {
	$validate -> username ($_POST['username']);
	$validate -> email ($_POST['email']);
	if ($irgendeinGrundTrotzemEinenErrorZuSchmeißen == $zbBereitsVorhandenerUsername) {
		$validate -> add_error ('username');
	}
	$error_style = $validate -> return_error_style();
	if ($validate -> error === false) {
		define ('ABSENDEN_IST_ERLAUBT','true');
	}
}
if (defined('ABSENDEN_IST_ERLAUBT')) {
	//Formular Auswerten
} else {
	if ($validate -> error === true) {
		echo 'Bitte fülle alle farblich makierten Felder korrekt aus';
	}
	echo '<form action="myURL" method="post">';
	echo '<input type ="text" name="username" value="' . $_POST['username'] . '"' . $error_style['username'] . ' />';
	echo '<input type="text" name="email" value="' . $_POST['email'] . '"' . $error_style['email'] . ' />';
	echo '<input type="submit" name="absenden" value="Absenden" />';
	echo '</form>';
}

Dann erstellst du nur noch in CSS eine Klasse .error und gibst der zum Beispiel einen roten Border.
Ich finde das ist eine ziemlich einfache Klasse, aber dafür Benutzerfreundlich. Kannst ja auch noch überprüfen ob if (isset($error_style['xyz'])) und kannst ausgeben, dass XYZ bitte so und so ausgefüllt werden muss.

edit:
Online geschrieben und viele viele Fehler in den Code gamacht, deswegen editiert.
 
Zuletzt bearbeitet:
Zumindest dein regulärer Ausdruck ist "falsch" ([email protected] ist eine zulässige E-Mail-Adresse). Ich halte an der Stelle alle Prüfungen, die mehr versuchen, als sicherzustellen "wir haben ein @ und wir haben hinten irgendwo 'nen Punkt" für relativ unsinnig, da auch eine formal korrekte Mail-Adresse noch lange nicht wirklich existieren muss.

Wo du eine Konstante nutzt, tut es auch eine Variable.

Zudem wäre es vielleicht mal eine Option, auf PHP5 umzusteigen. ;)
 
Zuletzt bearbeitet:
Zumindest dein regulärer Ausdruck ist "falsch" ([email protected] ist eine zulässige E-Mail-Adresse).
Hättest du einen guten für mich? Ich kenne mich mit regex nicht wirklich aus, sondern such die Ausdrücke aus dem Internet heraus.:cry: Oder Nochbesser, hast du ein gut verständliches Tutorial, ich finde keins.
Zudem wäre es vielleicht mal eine Option, auf PHP5 umzusteigen. ;)
Ja wird echt langsam Zeit, muss mir mal ein gutes TUT suchen.:oops:
 
Du meinst diesen Einwand?

Aber Dinge wie z.B. [email protected].q oder öäüß@dummy.x gehen bei dem Filter ohne Probleme als gültig durch.

Der Thread ist von 2007-2008. Die letzte Mail-Adresse gibt bei mir aktuell ein false zurück, die erste wird noch immer durchgelassen.

Ich hätte aber ehrlichgesagt in beiden Fällen kein Problem mit einem "true" (das heißt in diesem Fall mit dem Eingabestring), denn wie gesagt: [email protected] schafft es durch jeden Filter, was aber nichts daran ändert, dass sie nicht existiert. Das Filtern/Validieren kann nur dazu dienen, völlig offensichtliche Falscheingaben zu verhindern (so von wegen: Benutzer hat versehentlich falsche Angabe in E-Mail-Feld gesetzt oder ein "@" vergessen oder so).

Das Abgleichen mit einer Liste von zum Zeitpunkt x zulässiger Top-Level-Domains wird zum Zeitpunkt y außerdem bereits falsch sein. Den Stress, das aktuell zu halten, würde ich mir nicht aufladen wollen (selbst wenn sich nicht so oft etwas ändert).

- List of Internet top-level domains - Wikipedia, the free encyclopedia
- http://en.wikipedia.org/wiki/Proposed_top-level_domain

Also, ich habe keine Ahnung, ob der PHP-Filter völlig korrekt arbeitet, aber ich gehe erstmal davon aus, dass sich da jemand Gedanken gemacht hat und zu einer einigermaßen vernünftigen Lösung gekommen ist.
 
Afaik wurde filter_* in einigen PHP 5.2-Versionen gepatched, so dass es heute zuverlässig arbeiten sollte.
Abgesehen davon lassen viele eigene Lösungen auch gültige E-Mails nicht durch.
 
Ohne das filter_var hätte ich vielleicht sowas vorgeschlagen:

Code:
(1) "mindestes ein Zeichen, das kein @ und kein Whitespace ist"
(2) + "@"
(3) + "mindestes ein Zeichen, das kein @ und kein Whitespace ist"
(4) + "."
(5) + "mindestes ein Zeichen, das kein @ und kein Whitespace und kein . ist"

Die Tests zeigen, was dieser Ausdruck durchlässt und was nicht.

Der Ansatz ist, in jedem Fall "false negatives", also zu Unrecht geblockte Adressen, zu verhindern.

PHP:
<?php

$pattern = '/^[^@\s]+@[^@\s]+\.[^@\s.]+$/';

$tests['pass'] = array(
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '+@+.+'
);

$tests['fail'] = array(
    'test@example',
    'test@[email protected]',
    '@example.org',
    'test @example.org',
    'test@ example.org',
    'test@example .org',
    'test@example. org',
    ' [email protected]'
);

foreach ($tests['pass'] as $test) {
    if (preg_match($pattern, $test)) {
        // Match
    } else {
        echo 'FAIL (test should have passed): ' . $test;
    }
}

foreach ($tests['fail'] as $test) {
    if (preg_match($pattern, $test)) {
        echo 'FAIL (test should have failed): ' . $test;
    } else {
        // No match
    }
}

Ehrlichgesagt finde ich den Ausdruck aber fast schon wieder zu kompliziert...
 
Genau den Einwand meinte ich, wenn man sich mal die verwendeten PHP-Versionen im Netz so ansieht.....

Wenn es rein um die Gültigkeit einer Mail geht, kann man sowas verwenden:
PHP:
if(!preg_match( '/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/' , $mailadresse)) $fehler = "Keine g&uuml;ltige Mailadresse..";
Leider setzt die Filter-Funktion eine aktuelle PHP-Version voraus und wird sonst eben nahezu unwirksam. Einiges rutscht immernoch durch und Probleme entstehen auch dann, wenn die Codierung aus irgend einem Grund nicht korrekt übergeben wird.
 
Der Ausdruck ist auch wieder zu restriktiv, verursacht also "false negatives". Siehe [email protected]. Ich würde zudem meine Hand nicht dafür ins Feuer legen, dass an allen Stellen an Buchstaben nur A-Za-z zulässig sind.
 
Die Prüfung sollte dem internationalen rfc 2822 entsprechen, ich persönlich bestehe auf einer gültigen internationalen Mailadresse, die auch von Jedem eingegeben werden kann (Also Umlaute etc werden eleminiert) Quelle: RFC 2822 - Internet Message Format

Ich schliesse noch das eine oder andere aus, stimmt, der Ausdruck kann ja beliebig erweitert werden.
 
PHP:
preg_match('/^[a-z]+[a-z-0-9\._]*@([a-z0-9][a-z0-9-]+\.)+[a-z]{2,6}$/i',trim($email));

Bisher werder False Positive, noch umgekehrt gehabt ^^
 
Zum dritten Mal oder so: [noparse][email protected][/noparse] ist eine gültige E-Mail-Adresse, [noparse][email protected][/noparse] zum Beispiel ebenso.

- Email address. Sub-addressing - Wikipedia, the free encyclopedia

Wenn ich den RFC richtig lese (und er bindend ist), ist übrigens auch [noparse]{?}@example.org[/noparse] eine gültige E-Mail-Adresse.

- RFC 2822 - Internet Message Format
- RFC 5322 - Internet Message Format (die zitierten Teile scheinen auch in diesem neueren RFC unverändert zu sein)

RFC 2822 schrieb:
Code:
   An addr-spec is a specific Internet identifier that contains a
   locally interpreted string followed by the at-sign character ("@",
   ASCII value 64) followed by an Internet domain.  The locally
   interpreted string is either a quoted-string or a dot-atom.

Definition für dot-atom:

RFC 2822 schrieb:
Code:
atext           =       ALPHA / DIGIT / ; Any character except controls,
                        "!" / "#" /     ;  SP, and specials.
                        "$" / "%" /     ;  Used for atoms
                        "&" / "'" /
                        "*" / "+" /
                        "-" / "/" /
                        "=" / "?" /
                        "^" / "_" /
                        "`" / "{" /
                        "|" / "}" /
                        "~"

atom            =       [CFWS] 1*atext [CFWS]

dot-atom        =       [CFWS] dot-atom-text [CFWS]

dot-atom-text   =       1*atext *("." 1*atext)

Weitere Infos:

- Email address. Internationalization - Wikipedia, the free encyclopedia
- How to Find or Validate an Email Address (darin ein Absatz, der RFC 2822 kommentiert)

Der zuletzt verlinkte Artikel sagt im Prinzip alles (auch hinsichtlich "Praxisrelevanz").

Na ja, ich bleibe dabei, dass eine Prüfung wie "Wir haben nur ein @ und dahinter irgendwo noch mindestens einen Punkt." im Grunde ausreichend ist, weil alles andere die Gefahr von "false negatives" erhöht beziehungsweise bei Tippfehlern auch nicht hilft.
 
Zuletzt bearbeitet:
Zurück
Oben