Jochen: Funktion in PHP

Guten Morgen,

ich habe mit Funktionen in PHP noch nicht viel Ahnung und wollte Fragen ob ihr mir helfen könnt folgendes umzusetzen?

Hab eine MySQL Tabelle die so aussieht:

CREATE TABLE IF NOT EXISTS inhalte (
  id int(11) NOT NULL AUTO_INCREMENT,
  wo varchar(200) NOT NULL,
  titel varchar(200) NOT NULL,
  inhalt text NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

auf meiner Seite habe ich mehrere Seite wo ich Texte ausgeben lassen möchte. Bis jetzt habe ich dieses immer wie folgt gemacht:

  
$texte = "Select * from inhalte WHERE wo = 'impressum'";  
$resultTexte = mysql_fetch_object(mysql_query($texte));  

ist natürlich nervig auf allen Seiten immer wieder ein SQL zu schreiben. Kann man dieses nicht als eine Funktion schreiben?

Das Auslesen sieht so aus:

echo $resultTexte->inhalt

Wenn man es als Funktion machen würde, wie würde dann die Ausgabe aussehen und wie würde man den Wert z.B. "impressum" übergeben?

  1. Tach!

    ich habe mit Funktionen in PHP noch nicht viel Ahnung und wollte Fragen ob ihr mir helfen könnt folgendes umzusetzen?

    Da kann ich dir nur empfehlen, dir das Grundlagenwissen zu Funktion anzueignen.

    ist natürlich nervig auf allen Seiten immer wieder ein SQL zu schreiben. Kann man dieses nicht als eine Funktion schreiben?

    Natürlich.

    Wenn man es als Funktion machen würde, wie würde dann die Ausgabe aussehen und wie würde man den Wert z.B. "impressum" übergeben?

    Die Antwort dieser Frage wirst du kennen, wenn du dir die allgemeine Funktionsweise von Funktionen angeschaut hast. Das PHP-Handbuch hat dazu ein Kapitel Functions, von dem dich die ersten drei Abschnitte weiterbringen sollten. (Die Absätze zu Referenzen kannst du überspringen.)

    dedlfix.

    1. @@dedlfix:

      nuqneH

      Das PHP-Handbuch hat dahttp://www.php.net/manual/de/language.oop5.phpzu ein Kapitel Functions

      Welches es auch auf deutsch gibt.

      Aber vermutlich sollte man es gleich richtig machen und die Datenbankzugriffe in einer Klasse kapseln.

      Als Buch finde ich Professionelle Softwareentwicklung mit PHP5 nicht schlecht. Kann man kaufen oder frei im Netz lesen.

      Qapla'

      --
      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
  2. 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:(
    1. Hallo Martin,

      vielen vielen Dank für deine sehr ausführliche Beschreibung, ich habe dein Beispiel bei mir in die Seite eingesetzt, habe eine funktionen.php angelegt, diese in meiner index.php wie folgt eingebunden:

      require_once("plugin/funktionen.php");

      bin dann in die Datei "datenschutz" gegangen und habe dein echo eingefügt. Hab leider kein Text gesehen. Bin dann in die error.log gegangen und habe folgendes gesehen:

      [Fri Dec 27 12:30:22 2013] [error] [client xx.xx.xxx.xxx] PHP Catchable fatal error:  Object of class stdClass could not be converted to string in /data/www/b1/xx/html/xxx/seiten/datenschutz.php on line 6, referer: www.xxxx.de/

      Ich kann mit dieser Zeile leider überhaupt nichts anfangen. Was mache ich denn falsch?

      Wenn ich dich richtig verstanden habe muss ich mein Inhalt weiter über

      echo $resultTexte->titel und ~~~php echo $resultTexte->inhalt

        
      augeben lassen, richtig?  
      
      
      1. Hi,

        Wenn ich dich richtig verstanden habe muss ich mein Inhalt weiter über

        echo $resultTexte->titel und echo $resultTexte->inhalt

        augeben lassen, richtig?

        nein, falsch. Ich hatte dir den Funktionsaufruf doch extra anhand deines eigenen Beispiels gezeigt. Dass du außer ->titel noch weitere Werte aus der DB holst, ging aus deiner Beschreibung nicht klar hervor (auch wenn es eigentlich logisch ist).

        Also wirst du die Funktion wohl so umschreiben müssen, dass sie nicht direkt einen einzelnen String zurückgibt, sondern das ganze Objekt mit den Strings aus der DB. Allerdings wird dann der Nutzen der Funktion fragwürdig, da sie für jede Seite nur einmal aufgerufen werden muss - und an jeder Stelle, wo Werte für diese Seite aus der DB eingesetzt werden, muss man die ja bloß aus dem Objekt lesen, das man mit der DB-Abfrage am Scriptanfang befüllt hat.

        Ciao,
         Martin

        --
        Die letzten Worte des Hardware-Bastlers:
        Das Netzkabel lass ich wegen der Erdung lieber dran.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Hallo,

          danke für deine Erklärung, da ich noch am Anfang stehe ist mir das jetzt erstmal zu hoch muss das erst lernen, solange schreibe ich in jede Datei das SQL.

          1. @@Jochen:

            nuqneH

            da ich noch am Anfang stehe

            Deshalb hatte ich dir Lesestoff verlinkt. Kann ja nicht so schwer sein, unter „Grundlagen“ bei „Klassen“ nachzulesen.

            Qapla'

            --
            „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    2. Om nah hoo pez nyeetz, Der Martin!

      … mit dem Auswahloperator ->

      Wie spricht man eigentlich -> und => korrekt aus, wenn man mal etwas erklären muss?

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Sau und Sauron.

      1. Hallo Matthias,

        … mit dem Auswahloperator ->
        Wie spricht man eigentlich -> und => korrekt aus, wenn man mal etwas erklären muss?

        ööhm ...
        Bisher habe ich die immer als "Pfeil" gelesen (vor allem auch in C), wobei du mir erst jetzt bewusst vor Augen führst, dass es ja in PHP tatsächlich diese beiden Varianten mit unterschiedlicher Bedeutung gibt.
        Den => im Kopf der foreach-Schleife musste ich noch nie laut vorlesen ... ;-)

        Nachdenkliche Grüße
         Martin

        --
        Wer barfuß geht, dem kann man nicht die Schuld in die Schuhe schieben.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    3. Tach!

      function TextFromDB ($key)

      {
         $texte = "Select * from inhalte WHERE wo = '$key'";
         $resultTexte = mysql_fetch_object(mysql_query($texte));

      return $resultTexte;
      }

        
      Diese Funktion gibt (abgesehen vom übergangenen Datenbank-Fehlerfall) zwei mögliche Werte zurück: false oder ein Objekt.  
        
      
      > `echo TextFromDB('impressum');`{:.language-php}  
        
      Das echo gibt damit entweder nichts aus (bei false - den Fall hast du ja noch angesprochen) oder versucht das Objekt in einen String zu wandeln. Da (bei stdClass) kein \_\_toString() vorhanden ist, ergibt das [den von Jochen beobachteten Fehler](https://forum.selfhtml.org/?t=216024&m=1480089). Eine Ausgabe muss (abgesehen vom false-Fall) also ungefähr so aussehen:  
        
      `echo TextFromDB('impressum')->feldName;`{:.language-php}  
        
      Alternativ dazu kann das Funktionsergebnis in einer Variable abgelegt werden und dann auf die Eigenschaften zugegriffen werden.  
        
      ~~~php
      $text = TextFromDB('impressum');  
      echo $text->feldName;  
      echo $text->nochEinFeldName;
      

      dedlfix.