Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

In PHP-Klassen Eventhandler verwenden wie in Delphi

Anleitung Entwicklung PHP

Mitglied: Codehunter

Codehunter (Level 2) - Jetzt verbinden

08.07.2010, aktualisiert 09.07.2010, 8004 Aufrufe, 2 Kommentare

Diese Anleitung richtet sich an Programmierer welche sich sowohl in Borland Delphi als auch in PHP auskennen. Ich erläutere in einem einfachen Beispiel die Verwendung von Eventhandlern (Ereignissen) in PHP-Klassen.

Hallo zusammen!

Als langjähriger Delphi-Programmierer habe ich in PHP immer eines sehr vermisst: Den Komfort von Eventhandlern (auch bekannt als Ereignisse). Die Delphi-Dokumentation definiert Ereignisse einfach als Methodenzeiger welche wiederum als Eigenschaftsvariablen einer Klasse angegeben werden. Zwar kennt PHP Callback-Funktionen doch ist deren Handhabung mit call_user_func innerhalb einer Klasse umständlich, der Zugriff auf Funktionen außerhalb der Klassendeklaration IMHO unmöglich.

PHP kennt im Gegensatz zu Delphi keine Methodenzeiger. Man kann sich aber eine andere nützliche Eigenschaft des PHP-Interpreters zu Nutze machen. PHP behandelt Funktionsnamen wie Strings und kann Stringvariablen als Funktionsaufrufe nutzen.

Da es für diesen speziellen Anwendungsfall natürlich keinen Objektinspektor wie in Delphi gibt ähnelt die weitere Vorgehensweise stark der Entwicklung von visuellen Komponenten in Delphi sowie deren Test durch Erzeugung zur Laufzeit.

Ich habe dazu folgenden Beispielcode entwickelt. Er orientiert sich stark an den Delphi-Konventionen:
01.
<?php 
02.
 
03.
  /* Eine neue Klasse deklarieren *
04.
  class TObject { 
05.
 
06.
    /* Sichtbare Klassenvariable welche den Eventhandler aufnimmt *
07.
    public $OnStart
08.
 
09.
    /* Eine neue Klassenmethode deklarieren *
10.
    public function Start() { 
11.
 
12.
      /* Die Klassenvariable mit dem Eventhandler in eine lokale Variable 
13.
         kopieren */ 
14.
      $func = $this->OnStart; 
15.
 
16.
      /* Den Eventhandler aufrufen und ihm einen Parameter übergeben 
17.
         (beispielsweise einen Fortschrittszähler) */ 
18.
      if(function_exists($func)) { 
19.
        $func(1234); 
20.
21.
22.
 
23.
24.
   
25.
  /* Die Funktion des Eventhandlers definieren *
26.
  function ObjectStart($number) { 
27.
    echo $number
28.
29.
 
30.
  /* Oben deklarierte Klasse instantiieren *
31.
  $obj = new TObject; 
32.
 
33.
  /* Eventhandler der Klasseninstanz zuweisen *
34.
  $obj->OnStart = ObjectStart; 
35.
   
36.
  /* Klassenmethode aufrufen welche ihrerseits den Eventhandler aufruft *
37.
  $obj->Start(); 
38.
 
39.
?>
Einige Erläuterungen zum Quelltext:

Zeile 7: Hier wird eine Klassen-Membervariable OnStart als public deklariert. Diese nimmt später den Namen der Eventhandler-Routine als String auf.

Zeile 10: Hier wird eine Klassenmethode als public deklariert. Darin können z.B. Schleifen durchlaufen werden wobei innerhalb der Schleife z.B. der Eventhandler mit dem aktuellen Schleifenzählerstand aufgerufen wird.

Zeile 14: Hier wird der Inhalt der Klassen-Membervariable OnStart in eine lokale Variable der Klassenmethode kopiert. Funktionsaufrufe aus Stringvariablen heraus funktionieren nur mit lokalen Variablen.

Zeile 18: Mittels function_exists wird überprüft, ob der angegebene Funktionsname als Funktion exisitiert und im Codebaum erreichbar ist. Dies kann man entfernt mit dem Aufruf von if Assigned(OnStart) in Delphi vergleichen.

Zeile 19: Hier wird nun der Eventhandler aufgerufen. Ich habe hier beispielhaft nur eine numerische Konstante als Parameter mitgegeben. Dies kann natürlich jede Art von Variable sein.

Zeile 26: Hier wird eine einfache Funktion als Eventhandler deklariert. Ihre Parameterliste muss natürlich mit der kompatibel sein welche innerhalb der Klasse beim Eventhandler-Aufruf verwendet wird.

Zeile 27: Der Inhalt des Eventhandler-Parameters wird beispielhaft per echo ausgegeben.

Zeile 34: Der Membervariablen OnStart unserer Klasse wird nun der Name unserer Eventhandler-Funktion übergeben. Um mich der Delphi-Syntax etwas anzunähern habe ich mir die Eigenart von PHP zunutze gemacht, nicht in einfache oder doppelte Anführungszeichen gesetzte Zeichenfolgen als String zu behandeln. Allerdings erzeugt dies einen PHP-Hinweis dass dies keine definierte Konstante ist - mir ging es um Ähnlichkeit zur Delphi-Syntax. Besser man schreibt
01.
$obj->OnStart = 'ObjectStart';
oder
01.
$obj->OnStart = "ObjectStart"';
Zeile 37: Schließlich und endlich wird nun die Klassenmethode Start() aufgerufen welche unser Konstrukt in Gang setzt.

Jetzt könnte man das Ganze noch ein wenig auf die Spitze treiben in dem man dem Eventhandler ein Handle auf die Klasseninstanz mitgibt. Dies entpricht dann den in Delphi bekannten Sender-Variablen. Dadurch kann man mehreren Klasseninstanzen den selben Eventhandler zuweisen. Die einzelnen Klasseninstanzen lassen sich anschließend innerhalb des Eventhandlers über die Sender-Variable identifizieren. Hier ein entsprechend modifiziertes Codebeispiel:
01.
<?php 
02.
 
03.
  class TObject { 
04.
 
05.
    public $Name
06.
    public $OnStart
07.
     
08.
    public function __construct() { 
09.
      $this->Name = 'Object1'; 
10.
11.
 
12.
    public function Start() { 
13.
 
14.
      $func = $this->OnStart; 
15.
 
16.
      if(function_exists($func)) { 
17.
 
18.
        /* Den Eventhandler mit einem Handle auf die aktuelle Klasseninstanz 
19.
           und einem Zählparameter aufrufen */ 
20.
        $func($this, 1234); 
21.
22.
23.
 
24.
25.
   
26.
  function ObjectStart($sender, $number) { 
27.
    echo $number
28.
    echo '<br />'; 
29.
 
30.
    /* Hier wird über das Handle der Klasseninstanz auf eine Membervariable 
31.
       zugegriffen. Genausogut könnte man auf Klassenmethoden zugreifen */ 
32.
    echo $sender->Name; 
33.
34.
 
35.
  $obj = new TObject; 
36.
 
37.
  $obj->OnStart = ObjectStart; 
38.
   
39.
  $obj->Start(); 
40.
 
41.
?>
Ich hoffe, mein kleines PHP-Delphi-Crossover findet ein paar Anwender. Schließlich sind beide Programmiersprachen sehr komfortabel. Warum sollen sie dann nicht voneinander profitieren.

Grüssle
Cody
Mitglied: dog
08.07.2010 um 19:46 Uhr
PHP behandelt Funktionsnamen wie Strings und kann Stringvariablen als Funktionsaufrufe nutzen.

Und das kommt davon wenn man PHP programmiert ohne mal die Fehleranzeige einzuschalten...

01.
<?php 
02.
 
03.
  error_reporting(E_ALL|E_STRICT); 
04.
  ini_set('display_erros','On'); 
05.
   
06.
  function keks() { 
07.
    echo "Hallo"
08.
09.
   
10.
  $call = keks; 
11.
   
12.
  $call(); 
13.
 
14.
?>
PHP Notice: Use of undefined constant keks - assumed 'keks' in /private/var/folders/rk/rkpxTSHLGeKxWDx3wCuQbk+++TI/-Tmp-/untitled_1b9..php on line 10
PHP Stack trace:
PHP 1. {main}() /private/var/folders/rk/rkpxTSHLGeKxWDx3wCuQbk+++TI/-Tmp-/untitled_1b9..php:0

Hallo

Wenn schon, dann gib bitte auch einen String an und nicht eine Konstante!
Das ist eine Unart, die manche PHP-Programmier-Anfänger entwickeln und dafür sollten Sie gleich im Hinterhof an die Wand gestellt werden...

Zudem kann 5.3 Closures, weshalb man dann ohnehin folgendes schreibt:

01.
<?php  
02.
  $call = function() { 
03.
    echo "Hallo"
04.
  }; 
05.
   
06.
  $call(); 
07.
?>
Bitte warten ..
Mitglied: Codehunter
09.07.2010 um 08:15 Uhr
Zitat von dog:

Und das kommt davon wenn man PHP programmiert ohne mal die Fehleranzeige einzuschalten...
Das ist eine Unart, die manche PHP-Programmier-Anfänger entwickeln und dafür sollten Sie gleich im Hinterhof an die Wand
gestellt werden...

Na das lass mal lieber Ich hatte dies ja bewusst gemacht und auch als solches hier in der Anleitung kenntlich gemacht. Ich hätte nur mehr betonen sollen was die richtige Notation gewesen wäre.

Zudem kann 5.3 Closures, weshalb man dann ohnehin folgendes schreibt:

Zu den Closures muss ich sagen dass ich bis heute keine Zeit gefunden habe mich in 5.3 einzuarbeiten, leider. Anders herum betrachtet ist so mein Beispiel aber auch zu älteren Versionen kompatibel. Die 5.3 ist längst noch nicht auf allen Webhosting-Paketen angekommen (manche bieten tatsächlich noch 4.x an)

Danke für die Tips, ich ändere mal die Anleitung entsprechend.

Grüssle
Cody
Bitte warten ..
Neuester Wissensbeitrag
Internet

Unbemerkt - Telekom Netzumschaltung! - BNG - Broadband Network Gateway

(3)

Erfahrungsbericht von ashnod zum Thema Internet ...

Ähnliche Inhalte
Heiß diskutierte Inhalte
Switche und Hubs
Trunk für 2xCisco Switch. Wo liegt der Fehler? (17)

Frage von JayyyH zum Thema Switche und Hubs ...

Windows Server
Outlook Verbindungsversuch mit Exchange (15)

Frage von xbast1x zum Thema Windows Server ...

DSL, VDSL
DSL-Signal bewerten (14)

Frage von SarekHL zum Thema DSL, VDSL ...