SELFPHP

SELFPHP-Druckversion
Original Adresse dieser Seite:
http://www.selfphp.de/praxisbuch/praxisbuchseite.php?site=251&group=44
© 2001-2024 E-Mail SELFPHP Inh. Damir Enseleit, info@selfphp.de
© 2005-2024 E-Mail PHP5 Praxisbuch - Matthias Kannengiesser, m.kannengiesser@selfphp.de


Magische Methoden (Interzeptormethoden)


Die Interzeptormethoden oder auch magischen Methoden von PHP 5 werden automatisch beim Zugriff auf nicht bekannte Eigenschaften und Methoden eines Objekts, beim Versuch, ein Objekt einer nicht deklarierten Klasse zu erzeugen, sowie bei der Typumwandlung eines Objekts in einen String aufgerufen.


Einsatz von __autoload()

Die global verfügbare __autoload()-Funktion  kann verwendet werden, um eigentlich nicht definierte  Klassen nachzuladen. Wird auf eine nicht definierte Klasse zugegriffen, wird, falls vorhanden, __autoload() aufgerufen und ausgeführt. Ist __autoload() entsprechend implementiert, können Klassen bequem nachgeladen werden. Damit ist es möglich, Klassen zur Laufzeit erst einzubinden, wenn sie tatsächlich benötigt werden.

Das folgende Beispiel zeigt den einfachsten Fall der Verwendung von __autoload() und geht davon aus, dass alle Klassen in einer Datei deklariert sind, deren Name sich aus dem Namen der Klasse und der Dateiendung .php zusammensetzt.

Beispiel – einfacher Klassenlader mithilfe von _autoload()

<?php

function __autoload($klassenname)
{
  include_once("$klassenname.php");
}
$daten = new Kontakte($host, $nutzer, $passwort);
?>

In diesem Beispiel steht die Klasse Kontakte eigentlich nicht zur Verfügung, da sie weder definiert noch eingebunden ist. Beim Versuch, Kontakte zu instanziieren, wird __autoload() aufgerufen und die Klasse mit include_once() nachgeladen.

Hinweis: Ist die geforderte Klasse nach Ausführung der __autoload()-Funktion weiterhin unbekannt, so wird eine Fehlermeldung ausgegeben.


Einsatz von __call()

Die __call()-Funktion wird aufgerufen, wenn versucht wird, eine nicht deklarierte Methode mit einem Objekt aufzurufen. Mit der __call()-Methode ist es möglich, dem Funktionsaufruf Parameter an die __call()-Funktion zu übergeben. Der __call()-Funktion stehen dabei zwei Parameter zur Verfügung:

Hinweis: Die __call()-Methode wird zum Überladen von Methoden verwendet. Klassenmethoden können überladen werden, um eigenen in Ihrer Klasse definierten Code auszuführen, indem man diese speziell benannte Methode definiert.

Beispiel

<?php

class Handies
{
  public $anzahl = 0;
  
  function __call($funktionsname, $parameter)
  {
    $this->anzahl = count($parameter);
    echo "Aufruf von $funktionsname mit $this->anzahl Parameter \n";
    if ($this->anzahl > 0) print_r($parameter);
  }
}

$test = new Handies();
$test->SetzeHersteller("Nokia","Siemens");
$test->SetzePreise(99.95, 199.99, 50);

?>
{PSP}Ausgabe
Aufruf von SetzeHersteller mit 2 Parameter
Array
(
   [0] => Nokia
   [1] => Siemens
)
Aufruf von SetzePreise mit 3 Parameter
Array
(
   [0] => 99.95
   [1] => 199.99
   [2] => 50
)

Im folgenden Beispiel wird der Datentyp geprüft und anschließend an die passende Funktion übergeben!

<?php

// Datentyp prüfen via __call()
class Auswertung {

  function __call($eingabe,$inhalt) {

   if($eingabe=='pruefen') {

    if(is_integer($inhalt[0]))
        $this->ausgabe_integer($inhalt[0]);

    if(is_string($inhalt[0]))
        $this->ausgabe_string($inhalt[0]);

    if(is_array($inhalt[0]))
        $this->ausgabe_array($inhalt[0]);

   }

  }

  private function ausgabe_integer($daten) {
   echo("Der Wert " . $daten . " ist ein Integer!<br>");
  }

  private function ausgabe_string($daten) {
   echo("Der Wert " . $daten . " ist ein String!<br>");
  }

  private function ausgabe_array($daten) {
   echo("Die Werte " . implode(",", $daten) . " sind in einem Array!<br>");
  }

}

// Klassenaufruf
$test = new Auswertung();

$test->pruefen(3);
$test->pruefen("3");

$array = array(10,20,30);
$test->pruefen($array);
?>

Ausgabe
Der Wert 3 ist ein Integer!
Der Wert 3 ist ein String!
Die Werte 10,20,30 sind in einem Array!


Einsatz von __set() und __get()

Eine weitere Variante der __call()-Methode sind __set() und __get(). Mit ihnen kann man direkt beim Aufruf die Werte beeinflussen.  Die beiden Methoden sind spezielle Methoden, auf die von außerhalb der Klasse als Attribute zugegriffen werden kann, welche jedoch in der Klasse selbst als Methoden definiert vorliegen. Einer der wichtigsten Vorteile der Methoden ist, dass sie Eigenschaften erzeugen können, die von außerhalb wie Attribute erscheinen, die intern jedoch mit komplexen Abläufen arbeiten.


Funktionsweise von __set() und __get()

Wird auf Eigenschaften eines Objekts zugegriffen, die nicht explizit definiert sind, wird die __set()-Methode aufgerufen, um einen Wert zu definieren. Soll dieser Wert abgefragt werden, wird die __get()-Methode aufgerufen. Sind weder __set() noch __get() implementiert, kommt es bei einem Zugriff auf nicht definierte Eigenschaften zu Fehlern.

Eine Besonderheit stellt folgendes Verhalten der beiden Methoden dar:
{PSP}
Hinweis: Die __get()/__set()-Methoden werden zum Überladen von Mitgliedern verwendet. Klassenmitglieder können überladen werden, um eigenen in ihrer Klasse definierten Code auszuführen, indem man diese speziell benannten Methoden definiert.

Beispiel

<?php

class Handies
{
  private $mobils = array(
  "Nokia" => 10,
  "Siemens" => 20
  );
  
  public function __get($varname)
  {
    return $this->mobils[$varname];
  }
  
  public function __set($varname, $wert)
  {
    $this->mobils[$varname] = $wert;
  }
}

$handy = new Handies();

$handy->Nokia++;
$handy->Siemens++;

echo "Wert von Nokia: " . $handy->Nokia . "\n";
echo "Wert von Siemens: " . $handy->Siemens . "\n";

?>

Ausgabe
Wert von Nokia: 11
Wert von Siemens: 21

Einsatz von  __toString()

Die neue __toString() Methode ermöglicht es Ihnen, eine Typumwandlung vorzunehmen und ein Objekt in einen String umzuwandeln.

Verfügt eine Klasse in PHP 5 über eine __toString()-Methode, so wird sie aufgerufen, wenn ein Objekt der Klasse in einen String umgewandelt werden soll. So gibt das folgende Beispiel »Der Kontostand beträgt 9999.95 Euro.« aus anstatt Object id #1. Letzteres wäre der Fall, wenn die Klasse Bankkonto über keine __toString()-Methodendeklaration verfügen würde.

<?php

class Bankkonto {
  private $guthaben = 9999.95;

  public function __toString() {
    return sprintf('Der Kontostand beträgt %01.2f Euro.',$this->guthaben);
  }
}

$meinKonto = new Bankkonto;
print $meinKonto;

?>

Ausgabe
Der Kontostand beträgt 9999.95 Euro.