Skip to main content

Passwort-Validierungsfunktion

So erweiterst du die PHP Funktionalität mit eigenen, spezifischen Funktionen für dein Projekt
Der Hintergrund

Warum Funktionen schreiben?

Ist es dir auch schon passiert, dass du gedacht hast, "das habe ich doch schon mal geschrieben", oder dass du Code von einem Projekt zum anderen kopiert hast, und dann nur ganz leicht abändern musstest? Dies sind Momente, in denen eine Funktion sinn machen würde - du hast den Code schon, und wenn er mal in einer Funktion organisiert ist, musst du ihn in Zukunft gar nicht mehr abändern um ihn wiederverwenden zu können. Um dies zu erreichen, muss dein Code eine gewisse Abstraktion erhalten - von einem Code Snippet, das eine ganz bestimmte Situation abdeckt, hin zu einem Ablauf, der Dank der Eingabe von Parameter und dem Ausgeben in vielen Fällen genutzt werden kann. 

Bildlich ausgedrückt ähnelt eine Funktion - auch diejenigen, die im PHP Funktionsumfang schon existieren - einer Fabrik. Es wird gesagt, was wir anliefern sollen, und was wir erhalten werden, und dazwischen findet ein uns nicht bekannter Prozess statt. 

Daraus ergeben sich mehrere Vorteile:

  • Fasse deinen Code thematisch zusammen
    Du kannst zum Beispiel alle Funktionen, die du für die Validierung von Formularen je benötigen wirst, in einer Datei definieren, und sobald du diese einbindest, stellst du deinem Projekt alle benötigte Funktionalität dazu bereit.
  • Schaffe übersicht, lagere den Code aus
    Du kannst Code, den du immer wieder benötigst, in eine Funktionsdefinition auslagern, und so innerhalb deines Skripts nur noch den Aufruf platzieren - dies macht dein Skript übersichtlich und kurz, und wenn du die Funktion aussagekräftig benannt hast, auch sehr gut verständlich. Rufe einfach validate_password() auf, statt einen 10-zeiligen Ablauf zu platzieren.
  • Eigene Gültigkeitsebene - vermeide Konflikte mit deinem Skript
    Du musst dir keine Gedanken machen, wie du die Variablen in deiner Funktion benannt hast, und dass du vielleicht mit einer gleichnamigen Variable in deinem Skript etwas überschreibst, was du noch weiter unten im Skript benötigt hättest. Warum? Funktionen haben eine eigene Gültigkeitsebene und kapseln den Code so von deinem Skript ab. Das heisst, die Variable $password in deinem Skript hat nichts mit der Variable $password in deiner Funktionsdefinition zu tun, sie existieren beide auf ihrer eigenen Ebene.
  • Bereite dich auf OOP vor
    Funktionen sind, wenn man die Entwicklung der Programmierung betrachtet, sozusagen die Vorstufe von Klassen. Objektorientiertes Programmieren (OOP) ist technisch gesehen erst einmal nichts anderes, als die Funktionen noch einmal in einer weiteren Ebene zusammenzufassen. Dies bringt weitere Vorteile mit sich, schafft noch mehr Ordnung und noch weniger Redundanz im Code. Wenn du dich an das Schreiben und organisieren von Funktionen gewöhnt hast, bist du gedanklich schon auf dem Weg, dich mit OOP auseinanderzusetzen.

So geht's

Die hier beschreibenen Schritte kannst du auf jeden Code-Abschnitt anwenden, den du gerne wiederverwenden möchtest. Um sich mit dem Schreiben von Funktionen vertraut zu machen, ist es oft hilfreich, von einem bestehenden, funktionierenden Skript auszugehen, welches für einen Einzelfall geschrieben wurde. In diesem Beispiel wird die Validierung eines Passworts zur Funktion umgewandelt. Denn für Passworte bestehen meistens einige Anforderungen, die sich grundsätzlich nicht gross unterscheiden, jedoch je nach Projekt vielleicht etwas variieren. Ausserdem verändern sich die Anforderungen bezüglich Länge und enthaltene Zeichen mit der Zeit. Wenn deine Prüffunktion also durch Parameter angepasst werden kann, wirst du sie noch länger wiederverwenden können. 

Du kannst dich beim Aufbau der Funktion an die folgenden Regeln halten:

  • Skript-spezifisch: Was nur in diesem einen Fall gegeben ist, kann als Parameter übergeben werden
  • Projekt-spezifisch: Was nur für ein einzelnes Projekt gilt, kann in eine Konfigurationsdate als Konstante definiert werden
  • Allgemeingültig/Abstrakt: Der Rest sollte nun ein abstrakter, wiederverwendbarer Ablauf sein, der in der Funktion definiert werden kann

 Schaue dir also dieses Skript an und entscheide, was in welche "Kategorie" von Code gehört.

<?php 
$errors = array();

// Passwortregeln: 
$minLength = 8;
$minUpper = 1; 
$minLower = 1; 
$minSpecial = 1;

// Suchmuster (testen: https://regex101.com)
$patternLower = "#([a-z])#"; // kleinbuchstaben finden
$patternUpper = "#([A-Z])#"; // grossbuchstaben finden
$patternSpecial = "#[\W_]#"; // Sonderzeichen (Non-Word und _) finden

if( !empty($_POST['password']) ){
  
  // Länge überprüfen: 
  if( strlen($_POST['password'])<$minLength ){
    $errors[] = "Passwort muss mindestens $minLength Zeichen enthalten";
  }
  // Keine Leerzeichen
  if( strpos( $_POST['password'], " " ) !== false ){
    $errors[] = "Passwort darf keine Leerzeichen enthalten";
  }
  
  // Kleinbuchstaben überprüfen: 
  preg_match_all($patternLower, $_POST['password'], $matchesLower);
  $foundLower = count($matchesLower[0]);
  if( $foundLower < $minLower ){
    $errors[] = "Passwort muss mindestens $minLower Kleinbuchstaben enthalten";
  }
  // Grossbuchstaben überprüfen:
  preg_match_all($patternUpper, $_POST['password'], $matchesUpper);
  $foundUpper = count($matchesUpper[0]);
  if( $foundUpper < $minUpper ){
    $errors[] = "Passwort muss mindestens $minUpper Grossbuchstaben enthalten";
  }
  // Sonderzeichen überprüfen:
  preg_match_all($patternSpecial, $_POST['password'], $matchesSpecial);
  $foundSpecial = count($matchesSpecial[0]);
  if( $foundSpecial < $minSpecial ){
    $errors[] = "Passwort muss mindestens $minSpecial Sonderzeichen enthalten";
  }

}

echo count($errors) ? implode('<br>', $errors) : 'Alles gut!';
?>

 


Tips und Links

  • Halte dich an Konventionen bei der Benennung deiner Funktionen - so machst du dir das Nutzen deiner Funktionen einfacher. 
  • Kommentiere ausserdem deine Funktionen immer! So ersparst du dir, später den Code in deiner Funktion durchlesen zu müssen, um zu verstehen, was du mitgeben musst, und was zurückkommt. Dafür sind dir auch eventuell weitere beteiligte Personen sehr dankbar.
  • Halte deine Funktionen so abstrakt wie möglich: verwende keine spezifischen parameter, wo nicht unbedingt notwendig. Statt $_GET['name'] kannst du ein Array mit zu überprüfenden Werten übergeben, damit du pro Fall entscheiden kannst, ob du Werte aus $_GET oder aus $_POST (oder sonst wo her) überprüfen willst
  • Nutze Konstanten für die Konfiguration deines Projektes - Konstanten sind global und können ohne übergabe via Parameter in Funktionen genutzt werden. 
  • Teste deine regulären Ausdrücke auf einer Seite wie RegEx101, um zu sehen, ob sie die Anforderungen abdecken.
  • Challenge: schaffst du es, alle drei Muster zusammen in eine RegEx zu packen, so dass nur noch ein preg_match() ausgeführt werden muss? 
Mittel

Organisiere deinen Code!

Strukturiere Deinen Code und vermeide Redundanz durch Auslagerung und Wiederverwendung von mehrfach gebrauchten Abläufen.


Tags
Kategorie