Article
1 comment

Ist ein CMS ohne Datenbank kein CMS?

Vor einiger Zeit entspann sich eine kurze Diskussion zwischen Christian Aust und mir auf Twitter, die in einer Aussage von mir gipfelte, daß ich Content Management Systeme ohne Datenbank für nicht gut halte. Nun hat er ein Posting dazu geschrieben. Das möchte ich kurz beantworten.

  • Keine Datenbank, somit keine Migration: Das ist so nicht richtig. Migrationen entstehen, wenn sich das Datenmodell ändert. Auch Content auf der Platte in Textdateien hat ein inhärentes Datenmodell. Wenn sich das ändert, muß man alle Dateien einzeln durchgehen und umbauen. Das halte ich für schwieriger. Zudem existieren für alle CMSse, die ich kenne, Updater, die sowas im Hintergrund für mich erledigen.
  • Das Produktivsystem ist nicht dynamisch schreibbar: verstehe ich nicht ganz. Ist das Verzeichnis mit dem Content-Baum read-only? Wenn ich einen Hacker auf dem Rechner habe (durch eine OS Sicherheitslücke), dann ist das völlig egal. Wenn es sich um eine CMS Sicherheitslücke handelt, ist es auch egal, weil das Markdown der Contentdateien ja noch dynamisch durch das Ruby CMS müssen. Vielleicht verstehe ich das Argument auch einfach noch nicht.
  • Dateiverwaltung geschieht über Dateitools und Versionsmanagement: WordPress ist ein denkbar schlechtes Beispiel für gute Softwarearchitektur bzw. es ist ein brilliantes Beispiel dafür, was man alles nicht machen soll. Wie z.B. URLs oder Pfade der Installation in die Datenbank schreiben. Und das auch noch in serialisierten PHP Arrays. Ansonsten ist die bitemporale Datenhaltung in SQL Datenbanken ein seit langem gelöstes Problem.
  • Workflow-Management über git sign off et al.: Was daran jetzt leichter sein soll als den Workflow eines ausgewachsenen CMS zu nutzen weiß ich nicht. Gute CMSse bieten dieses Feature von Hause aus an.

Nesta CMS verwaltet seinen Content, wie ich auf der Webseite gelesen habe, in Markdown Dateien in einem separaten Verzeichnisbaum. Dieser Baum bildet dann nachher die URL-Pfade online ab. Ich werde wohl nie verstehen, warum man eine Markup-Sprache (HTML) durch eine andere (Markdown) ersetzt. Im Zweifelsfall stehen mir diese Dinger im Weg. Das Argument, daß ja nur ein bestimmtes erlaubtes Subset von HTML aus der anderen Markupsprache in HTML übersetzt wird und damit für mehr Sicherheit gesorgt wird ist ja auch nur ein gewisses Scheinargument. Das steht und fällt mit der Güte des Parsers.

Für größere Unternehmen eigent sich so ein filebasiertes CMS eher nicht, weil man hier z.T. zeitgleiche Schreibzugriffe auf einzelne Dateien hat. Das funktioniert eher schlecht. Beim Lesen des Contents gehe ich mal davon aus, daß hier der Filesystem Cache Kollisionen verhindert bzw. Zugriffe beschleunigt.
Es gibt ja auch noch CMSse, die allen Content in einer Datei speichern. Die sind dann auch noch beim Lesezugriff langsam.
Mein Fazit: Nicht jedes CMS ist für alles und jeden geeignet. Da spielen faktische Rahmenparameter genau so eine Rolle wie der persönliche Gusto des Benutzers. An einer Evaluation verschiedener Kandidaten führt wohl kein Weg vorbei.

Article
0 comment

Why you should not deploy web applications with unix packaging tools

Packaging and deploying web applications, e.g. PHP apps, can be a very tough topic. One way to deal with automatic deployment and dependencies is to use the packaging tools your unix server supplies, e.g. debian *.deb packages. This approach has indisputable benefits:

  • it manages dependencies
  • it’s possible to manage the deployment process on several servers automatically
  • there is a complete existing infrastructure for this task

But (you knew that would come, didn’t you?): packaging systems like the one used on debian are targeted to control that the package is installed in exactly one version (certainly not always, we’ll come to that later on) in one defined place. Igf we use multiple versions of the same software, it’s version number will define where they will be installed. You get a version tree like:

/usr/local/lib/…
…/applib-1.1/
…/applib-1.2/
etc.

Most system packaging tools also allow you to specify a prefix where to install the package. But altogether its a special tool for a special task.
Using it for web application deployment looks like the “if all you know is a hammer, every task looks like a nail” paradigm. You can accomplish the tasks needed but you have to modify the standard processes very much.
For example I would like to be able to install exactly the same software twice on exactly the same machine. And yes I absolutely definitely want to have two times the same version of the code in different locations. Here the notion of the packaging systems paradigm of a “system” as a whole server and not a virtual host or any other subdivision of a system is in the way.
I prefer to use build systems like phing, ant or make to wrap up things. Especially phing in combination with DbDeploy is a very comfortable way to do things you don’t want to handle manually in the PHP universe.

Article
0 comment

Dereferencing deeply nested arrays with array_reduce

Sometimes you need to grab a value from a deeply nested array and you get a path description to that value as a string. For example you get a path as

$path = “A.B.C.D.X”;

which refers to a value in an array like this:

$param[‘A’][‘B’][‘C’][‘D’][‘X’] = “Dorky”;

Now you would like to get the value “Dorky” only by using the string description in $path. You need to get every indexing step as a string value by exploding the string at the “.” characters.

$patharray = explode(”.”, $path);

Then you need to go along this path in array form and dereference the $param array down to its value. You could do so with a foreach loop on the $path array. But you can do it more elegant using array_reduce.
Normally array_reduce iterates over an array and gathers (in any sense) information to sum it up in some single value. But you can also replace this “sum variable” by something else. For example by a dereferenced value of an array … you get a clue?
And since we don’t want to pollute our namespaces with callback functions, why not use the new PHP5.3 feature of anonymous functions?
Putting it all together leads to a one liner:

$value = array_reduce(explode(’.’, $str), function($v, $w) { return $v[$w]; }, $param);

To try it out here is the complete script:

<?php
$str=“A.B.C.D.X”;
$param[‘A’][‘B’][‘C’][‘D’][‘X’]=“Dorky”;
$value=array_reduce(explode(’.’, $str), function($v, $w) { return $v[$w]; }, $param);
print_r($value);
?>

Have fun!