Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

CMS im Eigenbau Vom Konzept zum fertigen Content Management System. Ein Vortrag von Markus-Hermann Koch.

Ähnliche Präsentationen


Präsentation zum Thema: "CMS im Eigenbau Vom Konzept zum fertigen Content Management System. Ein Vortrag von Markus-Hermann Koch."—  Präsentation transkript:

1 CMS im Eigenbau Vom Konzept zum fertigen Content Management System. Ein Vortrag von Markus-Hermann Koch

2 1. Motivation2 1. Warum _noch_ ein CMS? Es gibt bereits eine Vielzahl guter, zum Teil sogar freier CMS. Joomla, Wordpress, Typo 3,... Diese werden seit Jahren entwickelt, bieten für vieles gute Standardlösungen und verfügen über ein ausgefeiltes Back End. Ihre Installation ist mitunter verblüffend einfach. Der Zeitaufwand einer Neuentwicklung ist hoch. Was spricht dagegen?

3 1. Motivation3 Was spricht dafür? Umsetzung selbstgewählter Standards. Nicht nur in punkto HTML, sondern auch in CSS, JavaScript, PHP und allen anderen Komponenten. Das System wird auf die Inhalte der Site angepasst und nicht andersherum. Sie verstehen Ihr System und wissen welche Änderungen für einen gewünschten Effekt erforderlich sind. Man kann dabei einiges lernen!

4 1. Motivation4 Warum das Original verwerfen?

5 1. Motivation5

6 6 Richtlinien für die Neufassung Wartbarkeit. Sämtlicher Quellcode soll mit Hilfe normaler Texteditoren vernünftig lesbar und bearbeitbar sein. Verzeichnisse sollen automatisch erzeugt werden. Trennung von Struktur und Textinhalt. Vermeidung von Redundanz. Insbesondere soll es eine einfach gestrickte, leere HTML- Vorlagendatei geben, die die immer gleiche Grundseite enthält und in die die eigentlichen Textinhalte über PHP eingefügt werden. Konsequenzen aus dem Original:

7 2. Die Vorlage index.php57 2. Aufbau der HTML-Vorlage <?php Einbinden der Initialisierungsskripte und der benötigten Objektklassen. Auswerten der _GET und _POST-Parameter. Davon abhängig: Welche CSS sollen eingebunden werden? Welche Inhalte werden aus der Datenbank/dem Cache geladen? Ggf. Datenbankinhalte in HTML umsetzen. Alle diese Daten in werden in Variablen abgelegt. (Das hält den HTML-Teil sauber und lässt den HTTP-Header lange variabel.) ?> DIV-orientierter Aufbau in den die Variablen eingefügt werden. CSS-Zen-Garden: http://www.csszengarden.com/tr/deutsch/

8 2. Die Vorlage index.php58 <?php require_once $_SERVER['DOCUMENT_ROOT']. '/init.php5'; require_once $i_root. $i_scripts. $i_kDB_fname;... [Weitere benötigte Objektklassen]... [Auswerten der _GET- und ggf. _POST-Parameter. Ggf. Auführung zusätzlicher Skripte]... [Laden der Linklisten, des Hauptinhaltes, inhaltsabhängiger CSS-Anweisungen und ggf. der Werbung aus der Datenbank und/oder dem Cache. Diese Daten werden in Variablen abgelegt]... [Ggf. Nachbearbeitung dieser Inhalte. Bis zu diesem Zeitpunkt wurde noch kein einziges Zeichen an den Browser geschickt.] ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

9 2. Die Vorlage index.php59... [Metadaten] <link rel='shortcut icon' type='image/x-icon' href=' /favicon.ico' /> <link rel='stylesheet' type='text/css' href=' ' media='all' /> <link rel='stylesheet' type='text/css' href=' ' media='all' /> <link rel='stylesheet' type='text/css' href='<?php echo $i_protocol.$i_html.$i_styles_karriere. $i_mainIE6_css_fname; ?>' media=' ' />

10 2. Die Vorlage index.php510... [Einbinden von Media-bezogenem CSS] getCssLink(); ?> KARRIERE handbuch - Koch Management Consulting ' type='text/javascript'> replaceAliases('{{IMG'.$i_gif_head.';kh}}')); ?>

11 2. Die Vorlage index.php511 <?php print(staticTools::linkList(1,20,array(2,7,11,14),$activeLink,'kh', NULL,$addLinksLeft,$db)); ?> <?php print(staticTools::linkList(23,40,array(1,4,7),$activeLink,'kh', NULL,$addLinksRight,$db)); ?>

12 2. Die Vorlage index.php512 <!--... [Einige Kommentare zum Code] Die Vorlage fuer dieses Template lieferte der Css Zen Garden. Eine wunderschoene Site, die sich der Verbreitung von CSS gewidmet hat. Da Sie offenbar Interesse an Quellcode haben, schauen Sie ruhig auch dort einmal vorbei: http://www.csszengarden.com/ P.S.: Diese Site verwendet keine Frames. Es ist also unerheblich ob Frames von Ihrem Browser unterstuetzt werden. ;-) -->

13 2. Die Vorlage index.php513 s wie im Zen-Garden CSS-Zen-Garden: http://www.csszengarden.com/tr/deutsch/

14 2. Die Vorlage index.php514 Interessante CSS-Eigenschaften Inhalte sollen gut aussehen auf IE 7+, Firefox 2+, Lynx. margin: auto: Zentriert relativ positionierte Blockelemente. float, clear: Erlauben und steuern das horizontale Nebeneinander von relativ positionierten Blockelementen. position: Ob relative, absolute, static oder fixed, mit position lassen sich die Blockelemente im Browser positionieren. overflow: Scrollbars in Blockelementen. Sehr empfehlenswert: http://de.selfhtml.org/

15 3. Die Programmstruktur15 3. Das wichtigste PHP Die vier zentralen Bausteine des CMS class khAction/fgAction : Enthalten Code für Funktionen die dynamischen Inhalt erzeugen. Diese Klassen werden aktiv, wenn ein GET/POST- Parameter ´action´ vorliegt und als Wert den Namen einer definierten Methode enthält. class htDisplay und Ableitungen: Verarbeiten die Datenbankinhalte zu HTML-Code oder PDF-Dokumenten. class Kdb : Ein eigenes Datenbankobjekt. Sämtliche DB-Zugriffe erfolgen über Instanzen dieses Objektes. init.php5 : Immer zuerst ausgeführtes Config-Script. Definiert globale, das CMS beschreibende Variablen und ruft seinerseits ein weiteres Script init.php5 auf, welches Daten zur Serverumgebung enthält.

16 4. Die Datenbankstruktur16 4. Die Datenbankstruktur

17 17 Diese bilden das Gros der Inhalte der Site. Die index_ -Tabellen stellen eine inhaltslose Baumstruktur voneinander abhängiger Index-Knoten zur Verfügung. Jedem Knoten ist eine cid (Content-Id) zugeordnet. Die cid entspricht einer Zeilennummer in den Tabellen content_ _. In den sprachbezogenen Content-Tabellen liegen die eigentlichen Überschriften und Textinhalte. Es kommen vier Arten von Inhalten vor: Standardinhalte, Werbeinhalte, statische Inhalte und dynamische Inhalte. a) Standardinhalte. Aus den SQL-Tabellen index_ und content_ _

18 4. Die Datenbankstruktur18 Auszüge aus der Index-Content-Struktur. Auszug aus index_kh Auszug aus content_de_kh

19 4. Die Datenbankstruktur19 Interessante SQL-Kommandos SHOW COLUMNS FROM : Liefert eine Tabelle mit Informationen über die Spalten der Zieltabelle zurück: Datentyp, Defaultwert, Primärschlüssel,... REGEXP : SQL kennt durchaus reguläre Ausdrücke! INNER JOIN : Nimmt beide Datensätze und liefert (als Menge betrachtet) ihr kartesisches Produkt zurück. So wird z.B. aus den Datensätzen (a,b,c) und (1,2) der Datensatz (a1,a2,b1,b2,c1,c2). Das ist toll! Bsp.: SELECT title FROM `index_kh` INNER JOIN `content_kh` ON `index_kh`. `cid` = `content_ _kh`. `id` WHERE `index_kh`.`id` = ; Liefert für beliebige den Title eines beliebigen des kh zurück. Sehr empfehlenswert: http://www.sqldocu.com/ Zeigt sehr viele seiner Kommandos auch als Code an: PHP-MyAdmin.

20 5. Die Darstellungsklassen20 5. Die Darstellungsklassen Disp In den Datenbankeinträgen und im Quellcode so wenig HTML wie möglich. HTML unterliegt schwankenden Standards. Keine Lust 10.000 Datenbankeinträge nachzubearbeiten! HTML-Code ist relativ umfangreich und Datenbankeinträge sollten einigermaßen schlank ausfallen. Meine Lösung: Trage Artikel in vereinfachter, am besten Fließtextform in die Datenbank ein. Weise dem Artikel eine Art zu. Z.B. twocol für zweispaltige Linklisten oder tabular für Inhalte, die Tabellen enthalten sollen. Schreibe Ableitungen twocolDisp und tabularDisp der Darstellungsklasse htDisplay, welche alle Fähigkeiten von htDisplay erben, aber diejenige Methode, die dort einfach nur die Inhalte aus der Datenbank holt, überschreibt: htDisplay->conTpl(..) liest einen Datenbankeintrag ein und liefert ihn zurück. twocolDisp->conTpl(..) liest ihn ein und verarbeitet ihn vor dem Zurückliefern. Bei Bedarf zusätzlich: Verfassen und Einbinden von twocolCon.css

21 5. Die Darstellungsklassen21 Aus der Datenbank auf den Monitor: Eine twocol-Linkliste Ebenfalls aus der Db: Der Content Converter für diesen Artikel ist twocol twocolDisp ergänzt den HTML-Header auch um einen Link auf twocolCon.css

22 5. Die Darstellungsklassen22 Manchmal praktisch: Ein Artikel - Zwei Displayer Für den Browser interpretiert von einem Objekt der Klasse standardDisp: Der Artikel, wie er in der Datenbank steht.

23 5. Die Darstellungsklassen23 Für den Acrobat Reader interpretiert von einem Objekt der Klasse standardPdf: Anmerkung: So etwas geht zügig und vergleichsweise einfach mit der Tool- Klasse des PHP-Open Source Projektes fpdf: http://www.fpdf.de/

24 5. Die Darstellungsklassen24 Interessante PHP5-Kommandos $cconv=twocolDisp; $displayer = new $cconv(...);... ist ein durchaus funktionierendes Codefragment! Sehr nützlich, wenn man den Namen der zu instanzierenden Klasse vorher nicht kennt. preg_replace(...) und eine Reihe verwandter Funktionen bringen die Möglichkeiten von Perl Regular Expressions nach PHP. (250 mal) header(...) muss aufgerufen werden, bevor das erste Zeichen an den Browser geschickt wurde. Erlaubt die Ergänzung des HTTP-Headers und somit z.B. Weiterleitungen (Location), veränderte MIME-Types (Content- Type), Browser-Cache-Kontrolle (Expires, Cache-Control, Pragma: no- cache) und vieles mehr. mb_detect_encoding(...), mb_convert_encoding(...): Umkodieren von Textinhalten zum Beispiel von UTF-8 in ASCII. Äußerst empfehlenswert: Programmieren mit PHP von Rasmus Lerdorf et Al. Erschienen im OReilly-Verlag. ISBN-10 3-89721-473-3.

25 6. Performance-Fragen25 6. Performance-Fragen Ich bezeichne einen Vorgang als teuer, wenn der Server für seine Bearbeitung stark beansprucht wird.

26 6. Performance-Fragen26 Festplatten-Caching: Nachdem der an den Client zu sendende Inhalt bestimmt wurde diesen parallel auch in einer Datei auf der Festplatte ablegen. Jedes mal wenn eine Anfrage an den Server geht erst überprüfen, ob der geforderte Inhalt nicht bereits in einer noch einigermaßen aktuellen Cache-Datei vorliegt und ggf. einfach diesen Inhalt laden. Meine Lösung: Die Cache-Dateien für die Hauptinhalte heißen content_ _ _ _.cch Sie sind per Default für 24h aktiv und gliedern sich intern in 2 Blöcke: HTML für den Header HTML für den eigentlichen Inhalt

27 6. Performance-Fragen27 Am Rande: Die Standardausgabe von PHP ist der Zielbrowser. PHP bietet aber einige Funktionen, die es erlauben die Ausgabe erst einmal in Variablen abzufangen. PHP-Stichworte dazu: ob_start(), ob_get_contents(), ob_end_clean() Anwendungsbeispiel auf Karrierehandbuch.de: Das Karrierehandbuch verfügt über ein auf bbPress laufendes Forum, dessen Funktionen dazu neigen, ihre Ausgaben direkt per print(...) auszugeben. Mit den ob_-Tools kann ich diese Ausgaben in Variablen abfangen, sie z.B. mit $displayer->replaceAliases(...) nachbearbeiten und erst dann anzeigen lassen. Ohne die gesamte BB-Press-Source überarbeiten zu müssen. BB-Press: http://bbpress.org/ Auf KH: http://www.karrierehandbuch.de/Extern/BBPress/index.php

28 6. Performance-Fragen28 Speicher-Caching: Insbesondere die Ergebnisse wiederholt auftretender SQL-Queries (etwa bei einfachen Aliasen) oder auch die Ausgaben komplexerer Methoden können parallel im Speicher abgelegt werden. Wird das Query oder die Methode aufgerufen schaut das Programm immer zuerst, ob bereits eine geeignete Variable mit dem Inhalt vorliegt. Es gibt viele kleine Informationsmethoden im CMS die immer wieder aufgerufen werden. Ohne Cache führt das bei einigermaßen komplexen Seiten schnell zu bis zu ca. 800 winzigen SQL-Queries. Allein durch konsequentes Speichercaching gelang es mir, die Geschwindigkeit der Site mehr als zu verdoppeln.

29 6. Performance-Fragen29 Objekt-Recycling: Das CMS enthält einige recht umfangreiche Objektklassen deren Instanzierung bereits teuer ist. Das ist besonders bei kleinen Funktionen, die zuweilen auch ein Displayer- oder ein Datenbankobjekt benötigen, schmerzhaft. Eine Lösung ist die optionale Übergabe einer Objektreferenz, die ggf. das teure new einspart: function tool(...,$dp=NULL,$db=NULL) //... { if (is_null($dp)) $dp = new htDisplay(..); if (is_null($db)) $db = new Kdb(..);... return $res; }

30 6. Performance-Fragen30 Objektorientierung nutzen! Schlanke Versionen von Klassen: Wird einfach nur ein Inhalt abgerufen, muss die Log-Klasse Ihrer Site nicht viel können. Es genügt, wenn Sie eine Zeile in einer Logdatei richtig zu schreiben vermag. Lediglich im Backend Ihres CMS benötigen Sie eine deutlich aufwändigere Log-Klasse, die Log-Dateien auch auswerten kann. Programmieren sie diese als Ableitung der einfachen Write-Only- Klasse! Beispiel: Anlegen einer Log-Klasse

31 6. Performance-Fragen31 Einige von meiner Erfahrung belegte, subjektive Feststellungen: PHP hat mehr Möglichkeiten, aber SQL arbeitet schneller. Der Flaschenhals ist die Schnittstelle zwischen PHP und SQL. 10 einfache, SQL-Kommandos sind teurer als 1 zehnfaches SQL-Kommando mit recht komplexem Query. Die Performance von SQL-JOINS in Kombination mit SQL-REGEXP- Ausdrücken ist durchaus eindrucksvoll. Beispiel: Die interne Suchmaschine des Karrierehandbuchs verwendet SQL und PHP parallel: Zunächst wird mit einem REGEXP-JOIN eine einfache Vorauswahl an möglichen Artikeln getroffen. Auf diese überschaubare Datenmenge werden dann die mächtigeren preg_- Methoden von PHP angewandt, die die Treffer auch bewerten.

32 7. All user input is evil32 7. All user input is evil Das CMS soll Dritten dienen, eigene Inhalte und ggf. sogar Dateien zu präsentieren. Dabei wird zwangsläufig die Sicherheitsfrage aufgeworfen. Bedrohung: SQL-Injection. Unter SQL-Injection versteht man den Versuch eines Users, durch kunstvolle Eingabe von Daten SQL-Kommandos zu manipulieren. Ein Beispiel: Das Programm erzeugt eine harmlose Anfrage aus einem Parameter SELECT ` ` FROM `content_de_kh`; Der User übergibt aber: passwd` FROM `userdata` WHERE `login`=´Admin´; -- SELECT `passwd` FROM `userdata` WHERE `login`=´Admin´; -- ` FROM `content_de_kh`;

33 7. All user input is evil33 Was kann man tun? Automatisch: Die PHP-Funktion mysql_query(..) lässt nur einen Befehl auf einmal zu. Gefährliche Zeichen `´\ -- nur kodiert in die SQL-Maschine einfüttern. Eben diese Zeichen für die genutzten Queries einsetzen. Also SELECT `broetchen` FROM `baecker`; anstelle von SELECT broetchen FROM baecker; Regelmäßig Datenbank-Backups ziehen. Hinweis: PHP bietet für die SQL-Schutzkodierung eigens die Kommandos addslashes($text) und stripslashes($text) an. Unicode-Fest ist mysql_real_escape_string($text,$dbResourceId) http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

34 7. All user input is evil34 Bedrohung: Cross Site Scripting. XSS (um es nicht mit CSS zu verwechseln) ist der Versuch eines bösartigen Autors z.B. Java-Script- Fragmente in seine Beiträge einfließen zu lassen, die etwa die Cookies eines diese Beiträge lesenden Admins auslesen und an den Hacker weiterleiten. Letzterer kopiert dann diese Cookies in seine eigenen HTTP- Requests und sieht für das CMS nun wie der Admin aus. Was kann man tun? Javascript aus User-Artikeln herausfiltern. Cookies an IPs knüpfen. Wer ein Cookie anfordert wird mitsamt seiner IP registriert ($_SERVER['REMOTE_ADDR']). Kommt nun eine Anfrage an den Server wird nicht nur der Wert des Cookies sondern auch die Korrektheit der IP überprüft. Das ist keine Garantie, aber schnell umgesetzt.

35 7. All user input is evil35 Was kann man tun? User-eigene Downloads nur in dafür vorgesehenen Verzeichnissen bereitstellen lassen. Auf Apache-Servern kann man in jedem Verzeichnis eine Datei.htaccess hinterlegen, in der man unter anderem festlegen kann, wie der Server mit zum Beispiel Perl - Dateien verfahren soll. Bedrohung: User stellen Schadskripte in Ihren Downloadbereichen bereit.

36 7. All user input is evil36 Beispiel für eine solche.htaccess-Datei: ForceType application/octet-stream Dieses Code-Fragment (die Regexp ist unvollständig) sorgt dafür, dass Scriptdateien bei Aufruf nicht ausgeführt, sondern einfach als Text an den Client gesendet werden.

37 7. All user input is evil37 Bedrohung: Abhören des Client beim Austausch vertraulicher Daten. Was kann man tun? Falls der Server-Dienst dies anbietet: Die Übertragung auf SSL (Secure Socket Layer) setzen und den Client seine Anfragen verschlüsseln lassen. Die meisten modernen Browser können sich ohne Aufwand für den User von der SSL anbietenden Site einen Public Key herunterladen, um damit zum Beispiel Formulardaten nach RSA zu verschlüsseln. Dazu genügt besucherseitig meist schon das Stellen der Anfrage als https://... anstelle von http://... Umsetzung: Auf meinem CMS gibt es eine Variable $i_protocol = http:// die bei der Erzeugung der internen Links eine wichtige Rolle spielt und deren Wert bei Bedarf auf https:// angepasst wird. FAQ zum Thema SSL: http://www.ccc.de/https/faq?language=de Kostenlose Zertifizierung: http://www.cacert.org/ Nette Einführung: Geheime Botschaften von Simon Singh.

38 8. Dinge, die ich gerne vorher gewusst hätte 38 8. Dinge, die ich gerne vorher gewusst hätte Regular Expressions sind das Werkzeug für die Bearbeitung von Strings. SQL bietet das Vergleichszeichen REGEXP an. PHP bietet ereg_..()- und preg_..()-Tools. preg steht für Perl Regular Expressions. Die preg-Tools sind besser als die ereg-Varianten. Die Anzahl der tatsächlich ausgeführten SQL Queries klein halten! Speicher- und Festplatten-Caching ist schnell programmiert und super! PEAR-DB wird von Rasmus Lerdorf empfohlen, ist aber bei der Verar- beitung von Strings buggy und führt bei Belastung zu Serverabstürzen. Die mysql_..()-Kommandos sind meiner Erfahrung nach zuverlässig. Auf Apache-Servern lohnt es sich, einmal die Datei httpd.conf entspannt durchzulesen..htaccess -Dateien erlauben die Konfiguration des Serververhaltens in beliebigen Verzeichnissen

39 CMS im Eigenbau39 Vielen Dank für Ihre Aufmerksamkeit!


Herunterladen ppt "CMS im Eigenbau Vom Konzept zum fertigen Content Management System. Ein Vortrag von Markus-Hermann Koch."

Ähnliche Präsentationen


Google-Anzeigen