JavaScript OOP für PHP-Entwickler

Für PHP-Entwickler ist es relativ schwer sich an die OOP von JavaScript zu gewöhnen. Das liegt daran, dass JavaScript-Klassen Prototype-basiert sind und die Klassen daher anders definiert werden als man es aus PHP, Java oder C# kennt. Um die Umstellung von PHP/Java/C# etwas leichter zu gestalten, habe ich mal ein JavaScript-PHP-Equivalent von zwei einfachen Klassen geschrieben, die exakt das gleiche tun.

Normale Klasse

Fangen wir mal an mit einer einfachen Person-Klasse, die nur einen Namen und die Anrede kennt und die Person ansprechen bzw. verabschieden kann.

Die Klasse in PHP:

<?php
class Person
{
	protected $name;
	protected $gender;
 
	public function __construct($name, $gender)
	{
		$this->name = $name;
		$this->gender = $gender;
		$this->sayHello();
	}
 
	public function sayHello()
	{
		echo "Hallo $this->gender $this->name.";
	}
 
	public function sayGoodbye()
	{
		echo "Bis bald $this->gender $this->name.";
	}
}

Und die gleiche Klasse in JavaScript:

View Code JAVASCRIPT
function Person(name, gender) {
	if(name && gender)
	{
		this.name = name;
		this.gender = gender;
		this.sayHello();
	}
}
 
Person.prototype.sayHello = function() {
	document.write("Hallo "+this.gender+" "+this.name+".");
};
 
Person.prototype.sayGoodbye = function() {
	document.write("Bis bald "+this.gender+" "+this.name+".");
};

Vererbung

Als nächstes eine einfache Vererbung. Es gibt eine zweite Klasse „Scientist“, die alle Eigenschaften und Methoden von Person erbt und sie um jeweils eine Eigenschaft und eine Methode erweitert.

Vererbung in PHP:

<?php
require_once 'Person.php';
 
class Scientist extends Person
{
	protected $department;
 
	public function __construct($name, $gender, $department)
	{
		$this->department = $department;
		parent::__construct($name, $gender);
	}
 
	public function research()
	{
		echo "$this->name forscht $this->department.";
	}
}

Und die gleiche Vererbung in JavaScript:

View Code JAVASCRIPT
function Scientist(name, gender, department) {
	Person.call(this, name, gender);
	this.department = department;
}
 
Scientist.prototype = new Person();
Scientist.prototype.constructor = Scientist;
Scientist.prototype.research = function() {
	document.write(this.name+" forscht "+this.department+".");
};

Aufruf der Klassen

Kommen wir nun zum leichtesten Teil – dem Aufruf bzw. Verwendung der Klassen. Hier unterscheiden sich JavaScript und PHP fast gar nicht.

PHP:

$einstein = new Person("Albert Einstein", "Herr");
echo "<br/>";
$einstein->sayGoodbye();
echo "<br/><br/>";
 
$newton = new Scientist("Isaac Newton", "Herr", "Physik");
echo "<br/>";
$newton->research();
echo "<br/>";
$newton->sayGoodbye();

Und in JavaScript:

View Code JAVASCRIPT
var einstein = new Person("Albert Einstein", "Herr");
document.write("<br/>");
einstein.sayGoodbye();
document.write("<br/><br/>");
 
var newton = new Scientist("Isaac Newton", "Herr", "Physik");
document.write("<br/>");
newton.research();
document.write("<br/>");
newton.sayGoodbye();

Die Ausgabe ist für beide identisch:

Hallo Herr Albert Einstein.
Bis bald Herr Albert Einstein.

Hallo Herr Isaac Newton.
Isaac Newton forscht Physik.
Bis bald Herr Isaac Newton.

Ich hoffe ich konnte euch damit die Unterschiede der beiden Sprachen klar machen. Wer möchte kann sich die Beispiele auch als ZIP-Archiv herunterladen.

Dependency Injection – kurz erklärt

Dependency Injection – klingt nach professioneller Programmierung. Aber was ist das eigentlich?
Wenn man nach Dependency Injection sucht, gibt es fast ausschließlich komplexe Erklärungen, die man nicht auf Anhieb versteht. Deshalb gibt es an dieser Stelle eine möglichst einfache Erläuterung von Dependency Injection in PHP.

Nehmen wir einmal an wir haben eine Klasse Gästebuch, die beim instanziieren ein Datenbank-Objekt erwartet.

class Guestbook
{
    /**
     * @var DatabaseDriver
     */
    protected $db;
 
    public function __construct(DatabaseDriver $db)
    {
        $this->db = $db;
    }
}

Jetzt ist es aber aufwendig bei jeder Erzeugung eines neuen Gästebuchs das Datenbank-Objekt zu übergeben, vor allem weil die Datenbank bei allen Gästebüchern die gleiche ist. Also wurde das Entwurfsmuster Dependency Injection entwickelt, das dieses Vorgehen vereinfachen soll.

class Guestbook
{
    /**
     * @var DatabaseDriver
     * @inject
     */
    protected $db;
 
    public function __construct()
    {
        $result = $this->db->query("SELECT * FROM guestbook");
        ...
    }
}

Dieses Beispiel funktioniert natürlich nicht ohne Weiteres, es zeigt aber die Idee hinter DI. Durch zum Beispiel die Angabe der Annotation @inject wird angezeigt, dass die Datenbank noch vor der Instanziierung von Guestbook eingefügt werden soll und wir damit quasi sofort arbeiten können.

In PHP gibt es diverse Frameworks, die das DI-Entwurfsmuster bereits implementieren. Dazu gehören unter anderem FLOW3, Zend Framework 2 und Symfony 2, aber eine wirklich saubere Lösung ist meiner Meinung nach noch nicht dabei. Bei FLOW3 beispielsweise werden die eigentlichen Klassen durch Fake-Klassen „überschrieben“, in denen dann das Inject vollzogen wird.
Wer DI also nutzen will, braucht in jedem Fall eine Logik, die das Inject überhaupt ausführt. Ohne Framework keine leichte Aufgabe.

Unsinnige Sprachkonstrukte und Funktionen in PHP?

In PHP exisitieren unheimlich viele Kontrollstrukturen und Funktionen. Klar, dass es dabei auch einiges gibt was man im Alltag eigentlich gar nicht braucht oder sauberer lösen kann oder vielleicht sogar unsinnig ist.

Mit den folgenden fünf Kontrollstrukturen musste ich persönlich noch nie arbeiten:

» Weiterlesen

Ältere Artikel »