Entwicklung

Das Model-View-Controller-Modell am Beispiel CakePHP

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Model, View und Controller: Begriffe, mit denen man nicht sofort etwas anfangen kann. Auch trotz vieler Erklärungen schreckt das, auf den ersten Blick komplizierte, Modell viele Menschen davon ab sich daran zu versuchen. Auch ich habe es erst nach drei Versuchen geschafft, was jedoch wahrscheinlich vorher an meiner Ungeduld scheiterte.

CakePHP

CakePHP Logo

Ich habe für diese Erklärung das Framework CakePHP benutzt, um einen Praxisbezug herzustellen und weil ich es gerade ausgiebig benutze. CakePHP ist ein offenes Web-Framework, das an Ruby on Rails angelehnt wurde. Die Prinzipien davon sind:

  • Don’t repeat yourself (Nichts zweimal programmieren)
  • Convention before configuration (Lieber alles nach einem festgelegten Muster benennen, als etwas einzustellen.)

Model

Model View Controller Prinzip
Model View Controller Prinzip (via Wikimedia Commons)

Das Model gibt die grundlegende Beziehung der Daten zueinander an. Es legt also das Datenmodell fest, in ihm wird der Name der Klasse festgelegt und hier wenden auch SQL-Joins definiert. Zudem stehen auch Aktionen, die vor dem Speichern in die Datenbank auszuführen sind, im Model.

Noch einmal am Beispiel einer CakePHP-Anwendung zur Arbeitserfassung von verschiedenen Benutzern:

<?php

class User extends AppModel{
	// Name der Klasse festlegen
	var $name = 'User';

	// Mit einem Join Tabellen verbinden
	var $hasAndBelongsToMany = array(
	    'Work' => array(
		'className' => 'Work'
	    )
	);
	 
	// Passwörter vor dem Speichern hashen
	function beforeSave($options) {
	    if (isset($this->data[$this->alias]['password'])) {
		$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
	    }
	    return true;
	}
}

?>

View

Der View stellt die Seite dar, die der Benutzer schließlich zu Gesicht bekommt. Es wird damit die Anzeige der Daten in HTML und PHP formuliert. Für (fast) jede Aktion im Controller (unten) muss ein View vorhanden sein.

Auch dazu wieder ein Beispiel:

<div class="page-header">
	<h1>Benutzer</h1>
</div>
<table class="table table-striped">
	<tr>
		<th>Id</th>
		<th>Benutzername</th>
		<th>Vorname</th>
		<th>Nachname</th>
		<th>Aktionen</th>
	</tr><?php foreach ($users as $user): ?>
	<tr>
		<td><?php echo h($user['User']['id']); ?></td>
		<td><?php echo h($this->Html->link($user['User']['username'], "/users/view/".$user['User']['id'])); ?></td>
		<td><?php echo h($user['User']['firstname']); ?></td>
		<td><?php echo h($user['User']['lastname']); ?></td>
		<td><?php echo h("<a href='" . $this->Html->Url(array('action' => 'edit', $user['User']['id'])) . "'><i class='icon-pencil'></i></a>"); ?>&nbsp; <?php echo h("<a href='" . $this->Html->Url(array('action' => 'delete', $user['User']['id'])) . "'><i class='icon-trash'></i></a>"); ?></td>
	</tr><?php endforeach; ?>
</table>

Controller

Der Controller definiert schließlich die verschiedenen Aktionen der Klasse. Das sind zum Beispiel users/index, users/view/2 und users/add, die als URL in der Anwendung erscheinen. Diese werden über gleichnamige Funktionen im Controller erstellt. In den Funktionen werden auch Daten aus der Datenbank gelesen und geschrieben. Ebenfalls im Controller findet die Überprüfung von Formulardaten statt.

Beispiel:

<?php
class UsersController extends AppController

{
	var $name = 'Users';

	// Überprüfung des Passwortes

	public $validate = array(

		'password' => array(
			'required' => array(
				'rule' => array(
					'minLength',
					'5'
				) ,
				'message' => 'Ein Passwort mit mindestens 5 Stellen wird benötigt'
			)
		)
	);

	// Alle Benutzer auflisten, $users steht in View "index" zu Verfügung

	function index()
	{
		$this->set('users', $this->User->paginate("all"));
	}

	// Einen Benutzer anzeigen, $user steht in View "view" zu Verfügung

	function view($id = null)
	{
		$this->User->id = $id;
		$this->set('user', $this->User->read());
		if (!$this->User->exists()) {
			throw new NotFoundException(__('Benutzer nicht gefunden!'));
		}
	}
}

?>

Zusammenfassung

Man kann zusammenfassend sagen, dass das Modell nicht so kompliziert ist wie sein Name. Wenn man es einmal verstanden und angewendet hat, kann man mit wenig Aufwand und schnell dynamische Webanwendungen schreiben, die beliebig erweiterbar sind.

Noch einmal kurz die drei Begriffe und ihre Bedeutung:

  • Model: Beziehung der Daten
  • View: Anzeige der Daten
  • Controller: Verarbeitung der Daten

edit: Artikel bearbeitet nach Hinweisen von ‘mar’.

Anderes

Was sonst noch war: Wieso DRM ein Unding ist

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Was ist DRM?

Digital Rights Management, abgekürzt DRM, was soviel heißt wie Digitale Rechtverwaltung, ist ein Verfahren mit dem man die Nutzung und Weitergabe digitaler Medien kontrollieren kann. Man kann damit zum Beispiel festlegen, dass ein digital vorliegendes Musikstück nicht kopiert werden oder nur eine bestimmte Zeit wiedergegeben werden darf.

Jetzt werden Sie sich denken: “Gut, die Künstler müssen ja schließlich auch Geld verdienen!”, aber Musik ist leider nicht der einzige Einsatzort.

Ein Gedankenexperiment

Fernseher

Stellen Sie sich vor: Sie haben einen neuen Fernseher der schicke Full-HD Sendungen anzeigen und diese sogar auf einer angehängten USB-Festplatte aufzeichnen kann. Dazu wird die Festplatte in einem nur von Linux zu lesenden Dateisystem formatiert und die Aufnahmen selbst noch einmal verschlüsselt.

Man kann in diesem Fall also wirklich davon ausgehen, dass diese Sendung außerhalb des Fernsehers niemand zu Gesicht bekommt.

Nach einer Weile setzen Sie sich vor den Fernseher und wollen eine Naturdoku von letzter Woche ansehen, die Sie auf die Festplatte aufgenommen haben. Sie stellen jedoch fest, dass sich diese gar nicht mehr abspielen lässt. DRM verbietet Ihnen diese Aufnahme nach dem Zeitraum von ein paar Tagen anzusehen. Sie haben die Sendung auf der Festplatte, dürfen sie aber nicht ansehen.

Nehmen Sie jetzt einen antiken Videorecorder und legen Sie eine VHS-Kasette von vor fünf Jahren ein. Und ja: Es funktioniert. Die Qualität ist zwar eher mittelmäßig, aber Sie dürfen das wenigstens.

Sie finden das abartig? Ja, ich auch. Gegen die Robotergesetze verstößt es übrigens auch.

Was denken Sie darüber?

Eigenes Projekt

RGB-LED Bibliothek für Arduino

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Während meiner Arbeit mit meinem neuen Arduino-Microcontroller habe ich eine Bibliothek für die Verwendung einer RGB-Led erstellt. Damit ist es möglich die Farbe der LED zu setzen und in einer bestimmten Zeitspanne die Farbe der LED langsam zu ändern.

Zur Verwendung muss man nur das zip-Paket herunterladen und im Arduino-Verzeichnis unter libraries abspeichern.

Farbe setzen

Um die Farbe zu ändern verwendet man die Methode setColor() wie folgt:

#include <RGBTools.h>

// Pins von Rot, Grün und Blau an der LED setzen
RGBTools rgb(9,10,11);

void setup(){
	rgb.setColor(255,0,0);
}

void loop(){
	// nothing to loop
}

Farbe fließend ändern

Um die Farbe über einen bestimmten Zeitraum hinweg fließend zu ändern verwendet man die Methode fadeTo():

#include <RGBTools.h>

// Pins von Rot, Grün und Blau an der LED setzen
RGBTools rgb(9,10,11);

void setup(){
	rgb.fadeTo(255,0,0,50,3000); // zu Rot in 50 Schritten + 3 Sekunden
}

void loop(){
	// nothing to loop
}

Anregungen für weitere Funktionen nehme ich gerne entgegen!

Download

Update: Bitte vom Github-Repository downloaden.

Entwicklung

Ampelschaltung mit Arduino

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Da ich mich jetzt im Besitz eines Arduino Mikrocontroller-Boardes befinde, nun ein erster Artikel über dieses faszinierende Stück Technik. Mit einem Arduino kann man einfach Elektronik ansteuern, wie zum Beispiel LEDs, Servos, Temperatursensoren usw., indem man ein Programm am Computer programmiert und dann über ein USB-Kabel auf das Board überträgt.

Für meinen ersten Artikel über dieses Thema habe ich mich für eine Ampelschaltung entschieden. Zwei Seiten einer Ampel, zum Beispiel bei einer Baustelle, sollen gesteuert werden. Wie bei einer österreichischen Straßenampel soll die Ampel außerdem grün blinken können.

Hardware

Ich habe dazu einen Arduino Uno und folgenden Aufbau verwendet:

Schaltbild

Achtung: Ich habe in diesem Aufbau die Widerstände für die Einfachheit weggelassen! Bitte LEDs nie ohne Vorwiderstand betreiben!

Jede LED ist dabei einzeln über einen Digitalport ansteuerbar. Ich habe aus Platzgründen die Ports 2,3,4,5,7 und 8 dafür verwendet.

Programmierung

Wie bei jedem Arduino-Sketch beginnt auch dieses Programm mit den beiden wohlbekannten Funktionen:

void setup(){

}

void loop(){

}

Als nächstes definieren wir nun am Beginn die digitalen Ausgänge der LEDs:

// Seite 1
int g_1 = 2;    // Grün
int y_1 = 3;    // Gelb
int r_1 = 4;    // Rot

// Seite 2
int g_2 = 8;    // Grün
int y_2 = 7;    // Gelb
int r_2 = 5;    // Rot

Im Setup-Teil des Programms werden dazu mittel pinMode( ) die Typen der Pins definiert:

pinMode(g_1, OUTPUT);
pinMode(y_1, OUTPUT);
pinMode(r_1, OUTPUT);

pinMode(g_2, OUTPUT);
pinMode(y_2, OUTPUT);
pinMode(r_2, OUTPUT);

Kommen wir nun zum eigentlichen Ampel-Programm. Dieser Teil des Codes befindet sich, damit er sich am Ende wiederholt, im loop( )-Teil. Ich habe dazu einfach nacheinander, unterbrochen mit delay( ) Aufrufen, die Vorgänge der Ampelschaltung prozedural programmiert. Natürlich wäre der Code mit OOP wesentlich übersichtlicher, dafür auch für den Anfang schwerer zu verstehen.

// Starteinstellung
digitalWrite(r_1, HIGH);    // Rot auf 1 ein
digitalWrite(g_2, HIGH);    // Grün auf 2 ein

// Grünphase von 2
delay(5000);                // Ampelphase mit z.B. 5 Sekunden Länge

// Ende der Grünphase von 2
blink(g_2, 4);                // Blinken am Ende der Grünphase
digitalWrite(g_2, LOW);        // Gründe Licht aus
digitalWrite(y_2, HIGH);    // Gelbes Licht ein
delay(1000);                
digitalWrite(y_2, LOW);        // Gelbes Licht aus
digitalWrite(r_2, HIGH);    // Rotes Licht ein

// Beginn der Grünphase von 1
delay(1000);
digitalWrite(y_1, HIGH);
delay(1000);
digitalWrite(r_1, LOW);
digitalWrite(y_1, LOW);
digitalWrite(g_1, HIGH);

// Grünphase von 1
delay(5000);

// Ende der Grünphase von 1
blink(g_1, 4);
digitalWrite(g_1, LOW);
digitalWrite(y_1, HIGH);
delay(1000);
digitalWrite(y_1, LOW);
digitalWrite(r_1, HIGH);
delay(1000);

// Beginn der Grünphase von 2
digitalWrite(y_2, HIGH);
delay(1000);
digitalWrite(r_2, LOW);
digitalWrite(y_2, LOW);

Zum Blinken der Ampel habe ich eine Funktion namens blink( ) verwendet. Diese stellt das Blinken der grünen Lampe am Ende der Grünphase in Österreich nach.

void blink(int pin, int times){
	for(int i = 0; i < times; i++){
		digitalWrite(pin, LOW);
		delay(500);
		digitalWrite(pin, HIGH);
		delay(500);
	}
}

Zusammenfassung

Mit diesem Code kann man nun bereits die “Ampelanlage” steuern. Sie sollte sich wie bei echten Vorbild verhalten. Hier nochmal der gesamte Code des Programmes:

int g_1 = 2;
int y_1 = 3;
int r_1 = 4;

int g_2 = 8;
int y_2 = 7;
int r_2 = 5;

void setup() {
	pinMode(g_1, OUTPUT);
	pinMode(y_1, OUTPUT);
	pinMode(r_1, OUTPUT);

	pinMode(g_2, OUTPUT);
	pinMode(y_2, OUTPUT);
	pinMode(r_2, OUTPUT);
}

void loop(){
	digitalWrite(r_1, HIGH);
	digitalWrite(g_2, HIGH);
	delay(5000);
	blink(g_2, 4);
	digitalWrite(g_2, LOW);
	digitalWrite(y_2, HIGH);
	delay(1000);
	digitalWrite(y_2, LOW);
	digitalWrite(r_2, HIGH);
	delay(1000);
	digitalWrite(y_1, HIGH);
	delay(1000);
	digitalWrite(r_1, LOW);
	digitalWrite(y_1, LOW);
	digitalWrite(g_1, HIGH);
	delay(5000);
	blink(g_1, 4);
	digitalWrite(g_1, LOW);
	digitalWrite(y_1, HIGH);
	delay(1000);
	digitalWrite(y_1, LOW);
	digitalWrite(r_1, HIGH);
	delay(1000);
	digitalWrite(y_2, HIGH);
	delay(1000);
	digitalWrite(r_2, LOW);
	digitalWrite(y_2, LOW);
}

void blink(int pin, int times){
	for(int i = 0; i < times; i++){
		digitalWrite(pin, LOW);
		delay(500);
		digitalWrite(pin, HIGH);
		delay(500);
	}
}

Natürlich kann man das typisch österreichische Ampelblinken auch weglassen und das Programm objektorient neu schreiben, aber an diesem Beispiel sieht man recht deutlich wie einfach und schnell sich so eine eigentlich komplexe Schaltung mittels Arduino verwirklichen lässt.

Der gesamte Code dieses Beispiels steht unter der CC-BY-SA-Lizenz.

Eigenes Projekt

Die Twitter-Anleitung für Einsteiger

Dieser Artikel ist älter als zwei Jahre und womöglich veraltet!

Ich habe in diesem Dokument einmal kurz zusammengefasst, was für Neulinge auf Twitter wichtig ist und was zu beachten ist. (Download als PDF)

Anregungen und Fragen dazu nehme ich natürlich über die Kommentare entgegen.