Der Martin: Funktion in PHP

Beitrag lesen

Moin,

ich habe mit Funktionen in PHP noch nicht viel Ahnung

kennst du das Konzept der Funktionen denn aus irgendeiner anderen Programmiersprache? Denn so grundverschieden sind die da alle nicht.

Eine Funktion wird in PHP mit dem Keyword 'function' deklariert, gefolgt vom gewählten Namen der Funktion, dann eine in Klammern gefasste Liste der Parameter, also variable Daten, mit denen die Funktion arbeiten soll. Diese Liste kann im Einzelfall auch leer sein, wenn die Funktion keine Parameter braucht; dann sind die Klammern eben leer.
Es folgt -in geschweiften Klammenr- der Anweisungsblock, der die eigentliche Funktion ausmacht, an dessen Ende steht in aller Regel das Keyword 'return' gefolgt von einem in der Funktion berechneten oder ermittelten Ausdruck, der an das aufrufende Programm zurückgegeben wird.

Gehen wir doch mal "in die Vollen".

$texte = "Select * from inhalte WHERE wo = 'impressum'";

$resultTexte = mysql_fetch_object(mysql_query($texte));

  
Wenn ich richtig verstehe, ist also 'impressum' der Teil, der immer wieder variabel ist. Das nehmen wir also als Parameter für die Funktion - ich nenne ihn hier mal $key (den Namen kann man beliebig, aber bitte sinnvoll wählen).  
Der Rest ist ja schon vorgegeben bzw. habe ich oben beschrieben:  
  
~~~php
function TextFromDB ($key)  
 {  
   $texte = "Select * from inhalte WHERE wo = '$key'";  
   $resultTexte = mysql_fetch_object(mysql_query($texte));  
  
   return $resultTexte;  
 }

Jetzt kannst du also überall dort, wo du sonst die zwei Zeilen mit der DB-Abfrage stehen hast, diese Funktion stattdessen aufrufen. Das ist erstens übersichtlicher, und zweitens musst du nur noch an einer Stelle ändern, falls sich an deiner DB-Struktur oder deren Schnittstelle mal etwas ändern sollte:

echo TextFromDB('impressum');

Aber HALT!!!
Haben wir nicht etwas sehr Wichtiges vergessen?
Ja, haben wir. Kontextgerechte Behandlung der Parameter. Und Fehlerbehandlung.

Was ist, wenn als Parameter etwas übergeben wird, was ungültige SQL-Syntax ergibt? Oder gültige Syntax, aber ein unsinniges Ergebnis? Was ist, wenn die Funktion mit einem Parameter wie etwa "' OR 1 --" aufgerufen wird? Bau diesen String mal in dein Query ein und überlege, was passiert. - Genau, du bekommst nicht *einen* Datensatz als Ergebnis, sondern sehr viele falsche.
Um zu verhindern, dass bestimmte Zeichen in einem anderen Kontext (hier: SQL) plötzlich als Code interpretiert werden, anstatt als Daten, muss man sie kontextgerecht maskieren oder escapen. MySQL (bzw. die PHP-Schnittstelle von mySQL) bringt die dafür am besten geeignete Funktion mysql_rela_escape_string() selbst mit. Damit können wir den Query-String in unserer eigenen Funktion nun "absichern":

$texte = "SELECT * FROM inhalte WHERE wo = ' . mysql_real_escape_string($key) . "'";

Ich habe hier übrigens die SQL-Keywords in Großschreibung umgesetzt; das ist kein Muss, aber eine in SQL übliche Gepflogenheit (in anderen Sprachen, etwa HTML, ist dagegen durchgehende Kleinschreibung üblich).

Die Problematik der kontextgerechten Behandlung von Werten wird übrigens in einem Artikel im SELFHTML-Wiki sehr ausführlich beschrieben.

Auf die Fehlerbehandlung kann ich hier nicht konkret eingehen, daher nur etwas allgemein: Jeder SQL-Aufruf *könnte* auch fehlschlagen. Sei es dass die DB, die man ansprechen wollte, gar nicht existiert, oder -hier im Beispiel wahrscheinlicher- dass ein gesuchter Schlüssel mal nicht exisitert. Dann würde mysql_fetch_object() kein Objekt mit dem gesuchten Feldinhalt liefern, sondern schlicht und einfach false. Dein Code würde aber trotzdem stur versuchen, auf das vermeintliche Objekt mit dem Auswahloperator -> zuzugreifen, und damit würde PHP auf die Schnauze fallen und eine Fehlermeldung schmeißen (ich bin mir nicht sicher, ob das Script dabei nicht sogar abgebrochen wird; ich glaube nein).

Solche vorhersehbaren Fehler muss man daher immer berücksichtigen. Untersuche das Ergebnis eines Funktionsaufrufs erst daraufhin, ob es auch das ist, was du erwartest und nicht das Kennzeichen für einen Fehlerfall, bevor du normal weitermachst. Hier könnte man im Fehlerfall eventuell einen Leerstring zurückgeben; ob ein solches Ersatz-Ergebnis Sinn ergibt, muss man aber von Fall zu Fall entscheiden. Manche Fehler kann man auf diese Weise überspielen, andere sind so schwerwiegend, dass man eigentlich nur noch das Script konktrolliert beenden kann, weil ein Fortsetzen sinnlos ist.

So long,
 Martin

--
Ich habe gerade erfahren, dass Tante Frieda gestorben ist. Der Tod hat sie im Schlaf ereilt. - Schrecklich. Dann weiß sie es also noch gar nicht?
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(