Top-Themen

Aktuelle Themen (A bis Z)

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

Mitglied: Codehunter

Codehunter (Level 2) - Jetzt verbinden

08.07.2010, aktualisiert 09.07.2010, 8106 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 ..
Ähnliche Inhalte
PHP

PHP RFC: Mcrypt Extension wird ab PHP 7.2 entfernt

Information von FrankPHP

Ein RFC ist grob eine Abstimmung unter den PHP-Entwicklern, um neue, bestehende oder alte Feature hinzuzufügen, zu ändern, oder ...

PHP

PHP 7.2 veröffentlicht

Information von FrankPHP

Das PHP-Team hat heute, den 30.11.207 die aktuelle Version von PHP 7.2 veröffentlicht. Eine der wichtigsten Änderungen für PHP-Entwickler ...

Administrator.de Feedback

Entwicklertagebuch: PHP 7

Information von admtechAdministrator.de Feedback4 Kommentare

Hallo Administrator User, mit dem heutigen Tag haben wir unsere Server komplett auf die PHP Version 7 umgestellt. Wir ...

Windows 10

Quato DTP94 unter Windows 10 x64 installieren und verwenden

Anleitung von anteNopeWindows 10

So hier mal wieder etwas Wissen für die Allgemeinheit. Quato gibt es seit einigen Jahren nun nicht mehr. Einige ...

Neue Wissensbeiträge
Humor (lol)
IoT-Gefahr: Smartes Aquarium leckt!
Information von Lochkartenstanzer vor 1 TagHumor (lol)3 Kommentare

Moin, Die IoT-Manie hat weitere Opfer gefunden. Ein Casino-Leck durch ein smartes Aquarium: Allerdings haben sie kein Wasser, sondern ...

Router & Routing

Alte Fritzbox 7270 mit VPN und SIP-Telefonie hinter O2 Homebox 6641 als "Modem"

Erfahrungsbericht von the-buccaneer vor 1 TagRouter & Routing3 Kommentare

Nun war es soweit: Auch O2 hat mich mit VOIP zwangsbeglückt. Heute am Privatanschluss, in 2 Wochen ist das ...

Sicherheit

Ungepatchte Remote Code Execution-Lücke in LG NAS

Information von kgborn vor 2 TagenSicherheit

Nutzt wer LG NAS-Einheiten? In den NAS-Einheiten der LG Network Storage-Einheiten gibt es eine sehr unschöne Schwachstelle, die einen ...

Windows Update

Neue Version KB4099950 NIC Einstellungen gehen verloren

Information von sabines vor 2 TagenWindows Update2 Kommentare

Es ist eine neue Version des KB4099950 verfügbar, die das Problem mit den verlorenen Netzwerkeinstellungen lösen soll. Das Datum ...

Heiß diskutierte Inhalte
Router & Routing
Mikrotik: Routing zwischen Interfaces mit Geräten ohne Gateway
Frage von TonLichtVideoRouter & Routing20 Kommentare

Hallo zusammen, ich komme aus dem Veranstaltungstechnik Bereich und habe zwei Netze um verschiedene Hardware zu Remoten. CONTROL1 192.168.1.0/24 ...

Linux Netzwerk
Raspberry Pi 3: WLAN Power save deaktivieren
Frage von nordie92Linux Netzwerk14 Kommentare

Moin moin, mein Raspberry Pi 3 Model B benötigt eine dauerhaft aktive WLAN-Verbindung. Leider bricht die WLAN-Verbindung nach einigen ...

Vmware
Server 2008 r2 vmware terminalserver
Frage von MasterCVmware11 Kommentare

Guten Abend zusammen, ich hoffe , dass einer von euch mir weiterhelfen kann ,bei meinem kack Problem ! Ist ...

VB for Applications
VBScript mit WINscp für einfachen FTP Transfer und nachträglichem verschieben der Datei in ein erledigt Verzeichnis
Frage von KeiosIDVB for Applications9 Kommentare

Hallo, leider soll ich auf den neueren Servern(Win2016R2) keine *.Bat Dateien mehr laufen lassen. Hier soll nun alles über ...