Wir erfinden die perfekte Programmiersprache

Es gibt so viele Programmier- und Skriptsprachen da draußen. Von PHP über Python, JavaScript bis hin zu Swift – nur richtig zufrieden bin ich mit keiner davon. Klar, jede Sprache hat seine Vor- und Nachteile und auch ihre Gebiete, wofür sie besonders gut geeignet ist. Aber warum gibt es eigentlich keine einfache Sprache, mit der man alles machen kann? C und C++ sind extrem mächtig, aber auch komplex und viel zu umständlich. PHP ist dagegen schön einfach, aber zu eingeschränkt in seinen Möglichkeiten. Bei Java trifft man auf einen Mittelweg, dafür erstickt man geradezu unter der Last der unzähligen Designpatterns. JavaScript wird von fast allen Plattformen unterstützt, besitzt aber keine echte Objektorientierung. Python-Code glänzt durch seine gut lesbare Struktur, wirkt auf mich aber immer angestaubt und veraltet (außerdem mag ich die Syntax nicht).

» Weiterlesen

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.