1. Einführung
Die Implementierung obligatorischer Objekttypen in PHP kann manchmal sehr wichtig sein. Wenn es fehlt, entweder aus mangelndem Wissen – basierend auf falschen Programmierannahmen oder einfach aus Faulheit – dann werden Sie in Ihrer speziellen Webanwendung Ergebnisse sehen, die Sie nicht erwarten. Insbesondere beim Programmieren in PHP 4 ist es sehr einfach, die Funktion „is_a()“ zu verwenden (obwohl es auch andere Methoden gibt), um den Typ des Objekts zu überprüfen, mit dem Sie arbeiten. Natürlich kann das Erzwingen von Objekttypen auch zum Filtern von Eingabeobjekten verwendet werden, die als Parameter an andere PHP-Klassen in derselben Anwendung übergeben werden müssen.
Allerdings weist PHP 4 einige Schwächen seines Objektmodells nicht auf – es kann gelegentlich erforderlich sein, zusätzlichen Code zu schreiben, um bestimmte Funktionen zu implementieren, die in ausgereiften objektorientierten Sprachen zu finden sind. Diese Tatsache ist der PHP-Community schon seit langem bekannt. Mit der Veröffentlichung von PHP 5 wurden jedoch viele dieser äußerst wertvollen Funktionen als Teil des verbesserten Objektmodells hinzugefügt. Sie helfen dabei, die objektbasierte Codeentwicklung besser umzusetzen und ermöglichen Ihnen die Nutzung spezifischer Objekteigenschaften.
Im oben genannten Fall ist besondere Vorsicht geboten, wenn es um Objekttypzwang geht. Tatsächlich bietet PHP 5 Entwicklern mindestens zwei Möglichkeiten, Objekttypen während der Ausführung einer Webanwendung zu überprüfen: den „Instanceof“-Operator und die „Type Hint“-Funktion. Wenn ich mich nun dem Hauptthema dieses Artikels zuwende, werde ich die Verwendung des „instanceof“-Operators in PHP 5 vorstellen. Sie werden bald feststellen, dass er sehr praktisch sein kann, um festzustellen, ob das Objekt, mit dem Sie arbeiten, zu einem bestimmten Typ gehört.
Dieser Artikel hilft Ihnen anhand einiger objektorientierter Beispiele zu verstehen, wie obligatorische Objekttypen in PHP 5 implementiert werden.
2. Was Sie nicht tun sollten
Um zu zeigen, wie man Objekttyp-Zwang in PHP 5 implementiert, verwende ich die (X)HTML-Widget-Klasse und eine einfache Seitenerstellerklasse mit einfachen Modifikationen, um sie an die PHP 5-Entwicklungsumgebung anzupassen.
Mein erstes Beispiel listet einige (X)HTML-Widget-Klassen auf, die von einer abstrakten Basisklasse „HTMLElement“ abgeleitet sind, die die Überprüfung des Typs ihrer Eingabeobjekte überspringt. Schauen Sie sich bitte zuerst die folgende Klasse an:
//Definieren Sie die abstrakte Klasse 'HTMLElement'
abstrakte Klasse HTMLElement{
geschützte $attribute;
geschützte Funktion __construct($attributes){
if(!is_array($attributes)){
throw new Exception('Ungültiger Attributtyp');
}
$this->attributes=$attributes;
}
// Abstrakte Methode 'getHTML()' abstrakte geschützte Funktion getHTML();
}
//Definieren Sie die spezifische Klasse 'Div'-extends HTMLElement
Klasse Div erweitert HTMLElement{
private $output='<div ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=$this->data.'</div>';
return $this->output;
}
}
//Definieren Sie die konkrete Klasse „Header1“ – erweitert HTMLElement
Klasse Header1 erweitert HTMLElement{
private $output='<h1 ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=$this->data.'</h1>';
return $this->output;
}
}
//Konkrete Klasse „Paragraph“ definieren – erweitert HTMLElement
Klasse Paragraph erweitert HTMLElement{
private $output='<p ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=$this->data.'</p>';
return $this->output;
}
}
//Definieren Sie die konkrete Klasse „UnorderedList“ – erweitert HTMLElement
Klasse UnorderedList erweitert HTMLElement{
private $output='<ul ';
private $items=array();
öffentliche Funktion __construct($attributes=array(), $items=array()){
parent::__construct($attributes);
if(!is_array($items)){
throw new Exception('Ungültiger Parameter für Listenelemente');
}
$this->items=$items;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
foreach($this->items as $item){
$this->output.='<li>'.$item.'</li>';
}
$this->output.='</ul>';
return $this->output;
}
}
Wie Sie sehen können, sind die (X)HTML-Widget-Klassen oben sehr nützlich, um bestimmte Elemente in einem Web zu generieren, aber ich habe den Code absichtlich für jede Klasse geschrieben, damit sie die Wirksamkeit der Eingabeparameter nicht überprüfen können. Wie Sie sich vielleicht vorstellen können, werden Eingabeparameter direkt an den Klassenkonstruktor übergeben und als Eigenschaften zugewiesen. Es stellt sich die Frage: Ist daran etwas falsch? Ja, das gibt es. Jetzt definiere ich meine einfachste Page Builder-Klasse und füttere sie mit Widgets wie diesem, damit Sie sehen können, wie die Eingabe in diese Klasse mit falschen Objekten vermischt wird. Hier ist die Signatur der Seitengeneratorklasse:
class PageGenerator{
private $output='';
privater $title;
öffentliche Funktion __construct($title='Default Page'){
$this->title=$title;
}
öffentliche Funktion doHeader(){
$this->output='<html><head><title>'.$this-
>title.'</title></head><body>';
}
öffentliche Funktion addHTMLElement($htmlElement){
$this->output.=$htmlElement->getHTML();
}
öffentliche Funktion doFooter(){
$this->output.='</body></html>';
}
öffentliche Funktion fetchHTML(){
return $this->output;
}
}
Nun beginnen wir mit der Instanziierung einiger (X)HTML-Widget-Objekte und deren Übergabe an die entsprechenden Generatorklassen, wie im folgenden Beispiel gezeigt:
try{
//Einige HTML-Elemente generieren $h1=new Header1(array('name'=>'header1', 'class'=>'headerclass'), 'Content for H1
Element kommt hierher');
$div=new Div(array('name'=>'div1','class'=>'divclass'),'Content für Div-Element
geht hier');
$par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraph
Element kommt hierher');
$ul=new UnorderedList(array ('name'=>'list1', 'class'=>'listclass'), Array
('item1'=>'value1', 'item2'=>'value2', 'item3'=>'value3'));
//Instanziiere die Seitengeneratorklasse $pageGen=new Page Generator();
$pageGen->doHeader();
//'HTMLElement'-Objekt hinzufügen $pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
//Webseite anzeigen echo $pageGen->fetchHTML();
}
Catch(Ausnahme $e){
echo $e->getMessage();
Ausfahrt();
}
Nachdem Sie den obigen PHP-Code ausgeführt haben, erhalten Sie als Ergebnis eine einfache Webseite – sie enthält einige zuvor erstellte (X)HTML-Objekte. In diesem Fall ist es leicht zu verstehen, was passiert, wenn die Page Builder-Klasse aus irgendeinem Grund ein falsches Objekt empfängt und ihre Methode „addHTML()“ aufruft. Hier habe ich die Konfliktbedingung überarbeitet – indem ich ein nicht vorhandenes (X)HTML-Widget-Objekt verwendet habe. Bitte schauen Sie sich den folgenden Code noch einmal an:
try{
//Einige HTML-Elemente generieren $h1=new Header1(array('name'=>'header1', 'class'=>'headerclass'), 'Content for H1
Element kommt hierher');
$div=new Div(array('name'=>'div1','class'=>'divclass'),'Content für Div-Element
geht hier');
$par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraph
Element kommt hierher');
$ul=new UnorderedList(array ('name'=>'list1', 'class'=>'listclass'), Array
('item1'=>'value1', 'item2'=>'value2', 'item3'=>'value3'));
//Instanziiere die Seitengeneratorklasse $pageGen=new Page Generator();
$pageGen->doHeader();
//'HTMLElement'-Objekt hinzufügen $pageGen->addHTMLElement($fakeobj) //Nicht vorhandenes Objekt an diese Methode übergeben $pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
// Die Seite anzeigen echo $pageGen->fetchHTML();
}
Catch(Ausnahme $e){
echo $e->getMessage();
Ausfahrt();
}
In diesem Fall, wie in der folgenden Zeile gezeigt:
$pageGen->addHTMLElement($fakeobj)//Nicht vorhandenes Objekt an diese Methode übergeben
Ein nicht vorhandenes (X)HTML-Widget-Objekt wird an die Seitengeneratorklasse this übergeben führt zu einem schwerwiegenden Fehler:
Schwerwiegender Fehler: Aufruf einer Mitgliedsfunktion für ein Nicht-Objekt in
Was ist mit
path/to/file
?Dies ist eine direkte Strafe dafür, dass der Typ des an die Generatorklasse übergebenen Objekts nicht überprüft wird! Denken Sie also unbedingt daran, wenn Sie Ihre Skripte schreiben. Glücklicherweise gibt es eine einfache Lösung für diese Probleme, und hier kommt die Leistungsfähigkeit des „instanceof“-Operators ins Spiel. Wenn Sie sehen möchten, wie dieser Operator verwendet wird, lesen Sie weiter.
3. Verwenden Sie den Operator „instanceof“.
Wie Sie sehen, ist die Verwendung des Operators „instanceof“ sehr einfach. Er verwendet zwei Parameter, um seine Funktion zu vervollständigen. Der erste Parameter ist das Objekt, das Sie überprüfen möchten, und der zweite Parameter ist der Klassenname (eigentlich ein Schnittstellenname), der verwendet wird, um zu bestimmen, ob das Objekt eine Instanz der entsprechenden Klasse ist. Natürlich habe ich die obige Terminologie absichtlich verwendet, damit Sie sehen können, wie intuitiv dieser Operator zu verwenden ist. Die grundlegende Syntax lautet wie folgt:
if (Objektinstanz des Klassennamens){
//Tue etwas Nützliches
}
Nachdem Sie nun verstanden haben, wie dieser Operator in PHP 5 verwendet wird, definieren wir die entsprechende Webseiten-Builder-Klasse, um den Objekttyp zu überprüfen, der an die Methode „addHTMLElement()“ übergeben wird. Hier ist die neue Signatur dieser Klasse, die, wie ich bereits erwähnt habe, den „instanceof“-Operator verwendet:
class PageGenerator{
private $output='';
privater $title;
öffentliche Funktion __construct($title='Default Page'){
$this->title=$title;
}
öffentliche Funktion doHeader(){
$this->output='<html><head><title>'.$this->title.'</title></head><body>';
}
öffentliche Funktion addHTMLElement($htmlElement){
if(!$htmlElement-Instanz von HTMLElement){
throw new Exception('Invalid (X)HTML element');
}
$this->output.=$htmlElement->getHTML();
}
öffentliche Funktion doFooter(){
$this->output.='</body></html>';
}
öffentliche Funktion fetchHTML(){
return $this->output;
}
}
Beachten Sie, dass in der obigen Klasse der Operator „instanceof“ in der Methode „addHTMLElement()“ enthalten ist, um sicherzustellen, dass alle übergebenen Objekte Instanzen der zuvor definierten Klasse „HTMLElement“ sind. Jetzt ist es möglich, die Webseite, die Sie zuvor gesehen haben, zu rekonstruieren. Stellen Sie in diesem Fall sicher, dass alle an die Webseiten-Builder-Klasse übergebenen Eingabeobjekte echte (X)HTML-Widget-Objekte sind. Hier ist das entsprechende Beispiel:
try{
//Einige HTML-Elemente generieren $h1=new Header1(array('name'=>'header1', 'class'=>'headerclass'), 'Inhalt für H1-Element geht hier');
$div=new Div(array('name'=>'div1', 'class'=>'divclass'), 'Inhalt für Div-Element kommt hierher');
$par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraph element goes here');
$teststr='Dies ist kein HTML-Element';
//Instanziiere die Seitengeneratorklasse $pageGen=new Page Generator();
$pageGen->doHeader();
//'HTMLElement'-Objekt hinzufügen $pageGen->addHTMLElement($teststr) //Einen einfachen String an diese Methode übergeben $pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->doFooter();
//Webseite anzeigen echo $pageGen->fetchHTML();
}
Catch(Ausnahme $e){
echo $e->getMessage();
Ausfahrt();
}
Wie Sie im obigen Beispiel gesehen haben, übergebe ich eine einfache Testzeichenfolge (kein „HTMLElement“-Objekt) an die Page Builder-Klasse, die eine Ausnahme auslöst – die von einem bestimmten „catch“-Block abgefangen wird, wie unten gezeigt:
Ungültiges (X)HTML-Element
Um die Gültigkeit des Eingabeobjekts zu bestimmen, habe ich zu diesem Zeitpunkt den Operator „instanceof“ verwendet, damit die obige Webseite angezeigt werden kann. Ich hoffe, Sie können wirklich verstehen, wie wichtig es ist, die Eingabe zu filtern Verwenden Sie die Methoden Ihrer Klasse, um unnötige Fehler zu vermeiden, indem Sie diesen Operator
verwenden (X). Für HTML-Widget-Klassen möchte ich diesen Operator als Teil ihrer „getHTML()“-Methode einbinden, um so die Erstellung von Webseiten zu ermöglichen, die verschachtelte (X)HTML-Elemente generieren.
4. Erweitern Sie die Verwendung des „instanceof“-Operators: Verschachtelte (X)HTML-Widgets
eignen sich gut für die Typprüfung von Eingabeobjekten, die direkt in die Seitenersteller-Funktionalität eingefügt werden. Jetzt gehe ich noch einen Schritt weiter und füge dem Konstruktor und der Methode „getHTML()“ der (X)HTML-Widget-Klasse eine Prüfroutine hinzu, damit sie andere Widgets als Eingabeparameter akzeptieren können. Bitte überprüfen Sie die folgenden Verbesserungen:
Klasse Div erweitert HTMLElement{
private $output='<div ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
if(!$data Instanz von HTMLElement&&!is_string($data)){
throw new Exception('Ungültiger Parametertyp');
}
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->Dateninstanz von HTMLElement)?
$this->data->getHTML():$this->data;
$this->output.='</div>';
return $this->output;
}
}
Klasse Header1 erweitert HTMLElement{
private $output='<h1 ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
if(!$data Instanz von HTMLElement&&!is_string($data)){
throw new Exception('Ungültiger Parametertyp');
}
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->Dateninstanz von HTMLElement)?
$this->data->getHTML():$this->data;
$this->output.='</h1>';
return $this->output;
}
}
Klasse Paragraph erweitert HTMLElement{
private $output='<p ';
private $data;
öffentliche Funktion __construct($attributes=array(),$data){
if(!$data Instanz von HTMLElement&&!is_string($data)){
throw new Exception('Ungültiger Parametertyp');
}
parent::__construct($attributes);
$this->data=$data;
}
//Die spezifische Implementierung der öffentlichen Funktion getHTML() der Methode „getHTML()“
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->Dateninstanz von HTMLElement)?
$this->data->getHTML():$this->data;
$this->output.='</p>';
return $this->output;
}
}
Klasse UnorderedList erweitert HTMLElement{
private $output='<ul ';
private $items=array();
öffentliche Funktion __construct($attributes=array(), $items=array()){
parent::__construct($attributes);
if(!is_array($items)){
throw new Exception('Ungültiger Parameter für Listenelemente');
}
$this->items=$items;
}
//Die spezifische Implementierung der Methode „getHTML()“.
öffentliche Funktion getHTML(){
foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
foreach($this->items as $item){
$this->output.=($item exampleof
HTMLElement)?'<li>'.$item->getHTML().'</li>':'<li>'.$item.'</li>';
}
$this->output.='</ul>';
return $this->output;
}
}
Wie in den obigen Klassen gezeigt, habe ich deren Konstruktoren bzw. „getHTML()“-Methoden umgestaltet, um die Implementierung verschachtelter (X)HTML-Elemente beim Generieren der entsprechenden Webseiten zu ermöglichen. Beachten Sie, dass ich den folgenden bedingten Block in den Konstruktor jeder Klasse eingefügt habe:
if(!$data exampleof HTMLElement&&!is_string($data)){
throw new Exception('Ungültiger Parametertyp');
}
An dieser Stelle stelle ich eigentlich sicher, dass nur String-Daten und Objekte vom Typ „HTMLElement“ als Eingabeparameter für jede Klasse zulässig sind. Andernfalls wird von der jeweiligen Methode eine Ausnahme ausgelöst, die dazu führen kann, dass die Anwendung die Ausführung stoppt. Dies ist also der Prozess der Überprüfung der Eingabedaten. Schauen wir uns nun die neue Signatur der Methode „getHTML()“ an, die auch den Operator „instanceof“ verwendet:
$this->output.=($this->data exampleof HTMLElement)?$this->data-
>getHTML():$this->data;
Wie Sie sehen, ist der Operator this in diesem Fall sehr nützlich, um die polymorphen Funktionen der (X)HTML-Widget-Klasse zu nutzen. Wenn das Attribut $data auch ein Widget ist, wird dessen Methode „getHTML()“ korrekt aufgerufen, was dazu führt, dass das verschachtelte Webelement angezeigt wird. Wenn es sich hingegen nur um eine Zeichenfolge handelt, wird sie direkt zu allen Ausgaben der aktuellen Klasse hinzugefügt.
An diesem Punkt haben Sie möglicherweise die Verwendung des „instanceof“-Operators in PHP 5 verstanden, um sicherzustellen, dass bestimmte Objekte zu einem bestimmten Typ gehören. Wie Sie in diesem Artikel sehen können, ist das Erzwingen von Objekttypen in PHP 5 eigentlich eine ziemlich einfache Aufgabe. Um Ihr Verständnis zu vertiefen, sollten Sie zunächst ein Beispiel für die Verwendung dieser Methode zum Filtern von Objekten in Ihrer PHP-Anwendung entwickeln.
5. Zusammenfassung
In diesem Artikel haben Sie gelernt, wie Sie den „instanceof“-Operator in PHP 5 verwenden, um den Typ Ihres Eingabeobjekts zu überprüfen. Die von mir gezeigte Methode ist jedoch nicht die einzige. In einem späteren Artikel werde ich Ihnen erklären, wie Sie die nette Funktion „Type Hinting“ in PHP 5 implementieren, die eine weitere Möglichkeit ist, die Objekttypisierung zu erzwingen.
Autor: Zhu Xianzhong Compiler Quelle: Tianji Development