Author: Progman, zuletzt bearbeitet von bigfoot @ 2004/06/22 22:08:22
Bitte beachten Sie, dass die Tutorialkapitel zusammenhängen. Wenn sie direkt auf ein Kapitel verlinkt wurden müssen Sie gegebenenfalls die vorherigen Kapitel auch lesen. Achten Sie beim lesen darauf, dass Sie kein Kapitel überspringen.
Eine HTML Klasse schreiben
- Warum eine HTML Klasse?
- Aufbau der Klassen
- Programmcode der HTMLempty-Klasse
- Programmcode der HTML-Klasse
1. Warum eine HTML Klasse?
Mir geht das langsam auf den Keks. Wir müssen die ganze Zeit mit echo(); arbeiten und die " escapen. Man könnte auch echo('...'); schreiben, aber dann geht kein \n mehr. Wir könnten aber auch echo('...' . "\n"); schreiben, find ich aber irgendwie scheisse. Desweiteren hab ich kein Bock mehr die HTML-Elemente von Hand zu schreiben. Ihr braucht ja nur ein < oder > schreiben, doch ich muss für das Tutorial immer < und >. Und das geht mir ehrlichgesagt langsam auf den Keks. Schön wäre es wenn ich eine HTML-Klasse habe. Einem Objekt solch einer Klasse kann ich dann die Attribute und den Inhalt übergeben. Letztendlich gebe ich dann das HTML-Element aus. Nun, dann schreib ich doch eine HTML Klasse.
2. Aufbau der Klassen
Wir schreiben 2 Klassen. Die eine heißt HTML und die andere heißt HTMLempty. Die erste Klasse sind für 'normale' HTML-Elemente, die HTMLempty Klasse nur für HTML-Elemente die keinen Inhalt haben, wie <hr /> oder <input />. Erstmal diskutieren wir die Klasse HTMLempty.
Im Konstruktor dieser Klasse wird dann der Name des Elements angegeben. Dieser wird als String übergeben. Der Funktionskopf sieht dann so aus.
// Konstruktor HTMLempty(string name);
Da ein HTML-Element auch Attribute besitzen kann, brauchen wir eine Methode, die die Attribute des Elements hinzufügt. Dieser Methode übergibt man dann ein Array mit den Werten und Namen der Attribute oder man übergibt der Methode 2 Parameter, wobei der erste dann der Name und der zweite dann der Wert des Attributs ist. Der Funktionskopf sieht dann so aus.
// Konstruktor HTMLempty(string name); // Methoden void addAttribut(mixed name [, mixed value]);
Der zweiter Parameter ist optional, weil er bei der Benutztung eines Arrays nicht gebraucht wird.
Als letztes brauchen wir noch eine Methode, die das HTML-Element auch ausgibt. Diese Methode hat einen optionalen Parameter. Mit dem wird angegeben, wie weit dieses Element eingerückt werden soll.
// Konstruktor HTMLempty(string name); // Methoden void addAttribut(mixed name [, mixed value]); void ausgeben([int indent]);
Nun setzen wir uns an die Klasse HTML. Diese Klasse unterscheidet sich nur geringfügig von der anderen Klassen, denn sie muss ja auch ein HTML-Element ausgeben. Sie sind sogar so ähnlich, dass wir die HTML-Klasse von der HTMLempty-Klasse ableiten können. Sie hat also die selben Methoden und Eigenschaften.
Die HTML-Klasse braucht aber noch eine zusätzliche Methode. Mit dieser Methode fügen wir den Inhalt des HTML-Elements ein. Dieser Methode wird dann ein String oder aber auch ein anderes Objekt der HTML-klassen übergeben.
// extend von HTMLempty void addInhalt(mixed content);
Das sind die Öffentlichen Methoden der Klasse, die man dann seinem End-Benutzern sagt, wie er diese Klasse benutzen soll. Nun geht es ans eingemachte. Wir schreiben zuerst die HTMLempty-Klasse.
3. Programmcode der HTMLempty-Klasse
Zuerst überlegen wir uns, welche Eigenschaften diese Klasse haben soll. Wir müssen einmal den Namen des HTML-Elements speichern. Als zweites müssen wir noch die Attribute dieses HTML-Elements irgentwo speichern. Die Attribute speichern wir in einem Array. Dies sind dann insgesammt zwei Eigenschaften.
<?php
class HTMLempty
{
var $_Name = "";
var $_Attribute = array();
}
?>
Nun kommt der Konstruktor dran. Dort müssen wir den Wert aus den Parameter in die Eigenschaft speichern. Na das ist ja nicht schwer. Dabei müssen wir den übergebene String prüfen, dass er ein gültiges HTML-Element entspricht.
<?php
function HTMLempty($name)
{
if(preg_match('/^[a-zA-Z.:][\w\-_.:]*$/i', $name))
{
$this->_Name = $name;
}
else
{
trigger_error("Unerlaubter Name für ein HTML-Element : '".$name."'",
E_USER_ERROR);
// wegen dem Tutorial habe ich den 2. Parameter in einer
// neuen Zeile geschrieben. Ihr könnt ihn ruhig hinter den anderen
// Parameter schreiben
}
}
?>
Nun schreiben wir unsere Methode um die Attribute hinzuzufügen. Wir beachten, dass der zweite Parameter optional ist.
<?php
function addAttribut($name, $wert = NULL)
{
if(isset($wert))
{
// zwei Parameter
$name = (string)$name;
if(preg_match('/^[a-zA-Z.:][\w\-_.:]*$/i', $name))
{
$this->_Attribute[$name] = $wert;
}
else
{
trigger_error("Unerlaubter Name für ein HTML-Attribut : '".$name."'",
E_USER_ERROR);
}
}
else
{
// ein Parameter
if(is_scalar($name))
{
// Dies braucht man, falls man Attribute hinzufügen
// will, die keinen Wert haben, wie man es bei
// <option selected> kennt
if(preg_match('/^[a-zA-Z.:][\w\-_.:]*$/i', $name))
{
$this->_Attribute[$name] = $name;
// Da wir gültiges HTML bzw XML schreiben
// muss jedes Attribut auch einen Wert haben
// selected wird dann zu selected="selected"
}
else
{
trigger_error("Unerlaubter Name für ein HTML-Attribut : '".$name."'",
E_USER_ERROR);
}
}
elseif(is_array($name))
{
// Jedes Arrayelement durchgehen
foreach($name as $key => $wert)
{
if(is_int($key))
{
// Arrayelement wurde mit $foo[] hinzugefügt
// also ohne Schlüssel. Ich nehme dann an
// das es sich um ein Attribut wie
// 'selected' oder 'readonly' handelt
if(preg_match('/^[a-zA-Z.:][\w\-_.:]*$/i', $wert))
{
$this->_Attribute[$wert] = $wert;
}
else
{
trigger_error("Unerlaubter Name für ein HTML-Attribut : '".$wert."'",
E_USER_ERROR);
}
}
else
{
$key = (string)$key;
if(preg_match('/^[a-zA-Z.:][\w\-_.:]*$/i', $key))
{
$this->_Attribute[$key] = $wert;
}
else
{
trigger_error("Unerlaubter Name für ein HTML-Attribut : '".$key."'",
E_USER_ERROR);
}
}
}
}
else
{
trigger_error("Erster Parameter muss ein Scalar oder ein Array sein",
E_USER_ERROR);
}
}
}
?>
Für die Methode ausgeben brauchen wir noch zwei andere Public-Methoden. Einmal die Methode getAttribut und die Methode getName. Sie müssen Public sein, weil die andere Klasse darauf zugreifen muss. Was diese Funktionen wohl machen ist klar.
<?php
function getName()
{
return $this->_Name;
}
function getAttribut()
{
return $this->_Attribute;
}
?>
Nun können wir uns an die Methode ausgeben dransetzen.
<?php
function ausgeben($indent = 0)
{
$str = str_repeat(' ', $indent);
$str .= "<".$this->getName();
$attrib = $this->getAttribut();
foreach($attrib as $name => $value)
{
$str .= ' '.$name.'="'.htmlspecialchars($value).'"';
}
$str .= " />\n";
echo($str);
}
?>
Un nun sind wir fertig mit dieser Klasse. Diese packen wir in unsere inc/classes.php.
4. Programmcode der HTML-Klasse
Zuerst vererben wir diese Klasse von der grad geschrieben Klasse.
<?php
class HTML extends HTMLempty
{
}
?>
Da diese Klasse auch noch den Inhalt eines HTML-Elements speichern muss, brauchen wir eine neue Eigenschaft.
<?php
class HTML extends HTMLempty
{
var $_Inhalt;
}
?>
Nun brauchen wir eine Funktion mit der wir den Inhalt des Elements hinzufügen.
<?php
function addInhalt($content)
{
if($classname = get_class($content))
{
$valid_classes = array('htmlempty', 'html');
if(in_array($classname, $valid_classes))
{
$this->_Inhalt[] = $content;
}
else
{
trigger_error('Ungültiges Objekt: "'.$classname.'"',
E_USER_ERROR);
}
}
elseif(is_scalar($content))
{
$this->_Inhalt[] = (string)$content;
}
else
{
trigger_error('Parameter muss ein Objekt oder Scalar sein',
E_USER_ERROR);
}
}
?>
Nun brauchen wir eine Methode die uns die Inhalte im Array $_Inhalt zurückliefern. Diese Funktion brauchen wir später noch.
<?php
function getInhalt()
{
return $this->_Inhalt;
}
?>
Nun schreiben wir eine Methode, die dieses HTML-Element ausgibt. Die Methode ausgeben können wir dazu nicht benutzen. Aber wir können diese Methode überschreiben.
<?php
function ausgeben($indent = 0)
{
$str_indent = str_repeat(' ', $indent);
$content = $this->getInhalt();
echo($str_indent."<".$this->getName());
$attribute = $this->getAttribut();
foreach($attribute as $name => $wert)
{
echo(' '.$name.'="'.$wert.'"');
}
echo(">\n");
foreach($content as $inhalt)
{
if(is_object($inhalt))
{
// der aktuelle Inhalt ist ein Object
// also ein HTML-Element. Also geben
// wir es aus
$inhalt->ausgeben($indent + 4);
// Rekursion lässt grüßen ...
}
else
{
// Inhalt ist ein String. Jeden Zeile
// geben wir getrennt aus
$zeilen = explode("\n", $inhalt);
$echo = "";
foreach($zeilen as $zeile)
{
$echo .= $str_indent." ".htmlspecialchars($zeile)."\n";
}
echo(nl2br($echo));
}
}
echo($str_indent."</".$this->getName().">\n");
}
?>
Nun haben wir unsere beiden Klassen fertig. Hier ein Beispielscript, wie man diese Klassen benutzt.
<?php
$form = new HTML("form");
$form->addAttribut('target', $_SERVER['PHP_SELF']);
$form->addAttribut('method', 'post');
$input = new HTMLempty("input");
$input->addAttribut('type', 'text');
$input->addAttribut('name', 'text');
$submit = new HTMLempty("input");
$submit->addAttribut('type', 'submit');
$submit->addAttribut('name', 'submit');
$p = new HTML("p");
$p->addInhalt("Bitte benutzen sie keine Zeichen wie < oder >.");
$form->addInhalt($input);
$form->addInhalt($submit);
$form->addInhalt($p);
$form->ausgeben();
?>
Nun brauche ich nichtmehr so oft echo() oder \" zu schreiben. Durch das Einrücken mit der Variable $indent wird sichergestellt, dass der HTML-Code richtig und leserlich eingerückt ist. Dies zeigt die Ausgabe des oben stehenden Codes.
<form target="/~progman/contest/bla.php" method="post"> <input type="text" name="text" /> <input type="submit" name="submit" /> <p> Bitte benutzen sie keine Zeichen wie < oder >. </p> </form>
Fragen zum aktuellen Thema
- Keine Übungsfragen
-
Zu diesem Kapitel gibt es keine Übungsfragen. Ehrlich gesagt fallen mir keine ein ;).