2       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
   3    <title>Kapitel 4. Entwicklerdokumentation</title><link rel="stylesheet" type="text/css" href="style.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.1-RC2"><link rel="home" href="index.html" title="kivitendo 3.4.1: Installation, Konfiguration, Entwicklung"><link rel="up" href="index.html" title="kivitendo 3.4.1: Installation, Konfiguration, Entwicklung"><link rel="prev" href="ch03s06.html" title="3.6. Schweizer Kontenpläne"><link rel="next" href="ch04s02.html" title="4.2. Entwicklung unter FastCGI"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Kapitel 4. Entwicklerdokumentation</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s06.html">Zurück</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch04s02.html">Weiter</a></td></tr></table><hr></div><div class="chapter" title="Kapitel 4. Entwicklerdokumentation"><div class="titlepage"><div><div><h2 class="title"><a name="d0e6158"></a>Kapitel 4. Entwicklerdokumentation</h2></div></div></div><div class="sect1" title="4.1. Globale Variablen"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="devel.globals"></a>4.1. Globale Variablen</h2></div></div></div><div class="sect2" title="4.1.1. Wie sehen globale Variablen in Perl aus?"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6164"></a>4.1.1. Wie sehen globale Variablen in Perl aus?</h3></div></div></div><p>Globale Variablen liegen in einem speziellen namespace namens
 
   4         "main", der von überall erreichbar ist. Darüber hinaus sind bareword
 
   5         globs global und die meisten speziellen Variablen sind...
 
   6         speziell.</p><p>Daraus ergeben sich folgende Formen:</p><div class="variablelist"><dl><dt><span class="term">
 
   7                      <code class="literal">$main::form</code>
 
   8                   </span></dt><dd><p>expliziter Namespace "main"</p></dd><dt><span class="term">
 
   9                      <code class="literal">$::form</code>
 
  10                   </span></dt><dd><p>impliziter Namespace "main"</p></dd><dt><span class="term">
 
  11                      <code class="literal">open FILE, "file.txt"</code>
 
  13                         <code class="varname">FILE</code> ist global</p></dd><dt><span class="term">
 
  14                      <code class="literal">$_</code>
 
  15                   </span></dt><dd><p>speziell</p></dd></dl></div><p>Im Gegensatz zu <span class="productname">PHP</span>™ gibt es kein
 
  16         Schlüsselwort wie "<code class="function">global</code>", mit dem man
 
  17         importieren kann. <code class="function">my</code>, <code class="function">our</code>
 
  18         und <code class="function">local</code> machen was anderes.</p><div class="variablelist"><dl><dt><span class="term">
 
  19                      <code class="literal">my $form</code>
 
  20                   </span></dt><dd><p>lexikalische Variable, gültig bis zum Ende des
 
  21               Scopes</p></dd><dt><span class="term">
 
  22                      <code class="literal">our $form</code>
 
  24                         <code class="varname">$form</code> referenziert ab hier
 
  25               <code class="varname">$PACKAGE::form</code>.</p></dd><dt><span class="term">
 
  26                      <code class="literal">local $form</code>
 
  27                   </span></dt><dd><p>Alle Änderungen an <code class="varname">$form</code> werden am Ende
 
  28               des scopes zurückgesetzt</p></dd></dl></div></div><div class="sect2" title="4.1.2. Warum sind globale Variablen ein Problem?"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6265"></a>4.1.2. Warum sind globale Variablen ein Problem?</h3></div></div></div><p>Das erste Problem ist <span class="productname">FCGI</span>™.</p><p>
 
  29                <span class="productname">SQL-Ledger</span>™ hat fast alles im globalen
 
  30         namespace abgelegt, und erwartet, dass es da auch wiederzufinden ist.
 
  31         Unter <span class="productname">FCGI</span>™ müssen diese Sachen aber wieder
 
  32         aufgeräumt werden, damit sie nicht in den nächsten Request kommen.
 
  33         Einige Sachen wiederum sollen nicht gelöscht werden, wie zum Beispiel
 
  34         Datenbankverbindungen, weil die sehr lange zum Initialisieren
 
  35         brauchen.</p><p>Das zweite Problem ist <code class="function">strict</code>. Unter
 
  36         <code class="function">strict</code> werden alle Variablen die nicht explizit
 
  37         mit <code class="function">Package</code>, <code class="function">my</code> oder
 
  38         <code class="function">our</code> angegeben werden als Tippfehler angemarkert,
 
  39         dies hat, seit der Einführung, u.a. schon so manche langwierige
 
  40         Bug-Suche verkürzt. Da globale Variablen aber implizit mit Package
 
  41         angegeben werden, werden die nicht geprüft, und somit kann sich
 
  42         schnell ein Tippfehler einschleichen.</p></div><div class="sect2" title="4.1.3. Kanonische globale Variablen"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6298"></a>4.1.3. Kanonische globale Variablen</h3></div></div></div><p>Um dieses Problem im Griff zu halten gibt es einige wenige
 
  43         globale Variablen, die kanonisch sind, d.h. sie haben bestimmte
 
  44         vorgegebenen Eigenschaften, und alles andere sollte anderweitig
 
  45         umhergereicht werden.</p><p>Diese Variablen sind im Moment die folgenden neun:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
 
  46                      <code class="varname">$::form</code>
 
  47                   </p></li><li class="listitem"><p>
 
  48                      <code class="varname">%::myconfig</code>
 
  49                   </p></li><li class="listitem"><p>
 
  50                      <code class="varname">$::locale</code>
 
  51                   </p></li><li class="listitem"><p>
 
  52                      <code class="varname">$::lxdebug</code>
 
  53                   </p></li><li class="listitem"><p>
 
  54                      <code class="varname">$::auth</code>
 
  55                   </p></li><li class="listitem"><p>
 
  56                      <code class="varname">$::lx_office_conf</code>
 
  57                   </p></li><li class="listitem"><p>
 
  58                      <code class="varname">$::instance_conf</code>
 
  59                   </p></li><li class="listitem"><p>
 
  60                      <code class="varname">$::dispatcher</code>
 
  61                   </p></li><li class="listitem"><p>
 
  62                      <code class="varname">$::request</code>
 
  63                   </p></li></ul></div><p>Damit diese nicht erneut als Müllhalde missbraucht werden, im
 
  64         Folgenden eine kurze Erläuterung der bestimmten vorgegebenen
 
  65         Eigenschaften (Konventionen):</p><div class="sect3" title="4.1.3.1. $::form"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6362"></a>4.1.3.1. $::form</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Ist ein Objekt der Klasse
 
  66               "<code class="classname">Form</code>"</p></li><li class="listitem"><p>Wird nach jedem Request gelöscht</p></li><li class="listitem"><p>Muss auch in Tests und Konsolenscripts vorhanden
 
  67               sein.</p></li><li class="listitem"><p>Enthält am Anfang eines Requests die Requestparameter vom
 
  68               User</p></li><li class="listitem"><p>Kann zwar intern über Requestgrenzen ein Datenbankhandle
 
  69               cachen, das wird aber momentan absichtlich zerstört</p></li></ul></div><p>
 
  70                   <code class="varname">$::form</code> wurde unter <span class="productname">SQL
 
  71           Ledger</span>™ als Gottobjekt für alles missbraucht. Sämtliche
 
  72           alten Funktionen unter SL/ mutieren <code class="varname">$::form</code>, das
 
  73           heißt, alles was einem lieb ist (alle Variablen die einem ans Herz
 
  74           gewachsen sind), sollte man vor einem Aufruf (!) von zum Beispiel
 
  75           <code class="function">IS->retrieve_customer()</code> in Sicherheit
 
  76           bringen.</p><p>Z.B. das vom Benutzer eingestellte Zahlenformat, bevor man
 
  77           Berechnung in einem bestimmten Format durchführt (SL/Form.pm Zeile
 
  78           3552, Stand version 2.7beta), um dies hinterher wieder auf den
 
  79           richtigen Wert zu setzen:</p><pre class="programlisting">  my $saved_numberformat    = $::myconfig{numberformat};
 
  80   $::myconfig{numberformat} = $numberformat;
 
  81   # (...) div Berechnungen
 
  82   $::myconfig{numberformat} = $saved_numberformat;</pre><p>Das Objekt der Klasse Form hat leider im Moment noch viele
 
  83           zentrale Funktionen die vom internen Zustand abhängen, deshalb bitte
 
  84           nie einfach zerstören oder überschreiben (zumindestens nicht kurz
 
  85           vor einem Release oder in Absprache über bspw. die devel-Liste ;-).
 
  86           Es geht ziemlich sicher etwas kaputt.</p><p>
 
  87                   <code class="varname">$::form</code> ist gleichzeitig der Standard Scope
 
  88           in den <span class="productname">Template::Toolkit</span>™ Templates
 
  89           außerhalb der Controller: der Ausdruck <code class="function">[% var
 
  90           %]</code> greift auf <code class="varname">$::form->{var}</code> zu.
 
  91           Unter Controllern ist der Standard Scope anders, da lautet der
 
  92           Zugriff <code class="function">[% FORM.var %]</code>. In Druckvorlagen sind
 
  93           normale Variablen ebenfall im <code class="varname">$::form</code> Scope, d.h.
 
  94           <code class="function"><%var%></code> zeigt auf
 
  95           <code class="varname">$::form->{var}</code>. Nochmal von der anderen Seite
 
  96           erläutert, innerhalb von (Web-)Templates sieht man häufiger solche
 
  97           Konstrukte:</p><pre class="programlisting">[%- IF business %]
 
  98 # (... Zeig die Auswahlliste Kunden-/Lieferantentyp an)
 
  99 [%- END %]</pre><p>Entweder wird hier dann $::form->{business} ausgewertet
 
 100           oder aber der Funktion
 
 101           <code class="function">$form->parse_html_template</code> wird explizit
 
 102           noch ein zusätzlicher Hash übergeben, der dann auch in den
 
 103           (Web-)Templates zu Verfügung steht, bspw. so:</p><pre class="programlisting">$form->parse_html_template("is/form_header", \%TMPL_VAR);</pre><p>Innerhalb von Schleifen wird
 
 104           <code class="varname">$::form->{TEMPLATE_ARRAYS}{var}[$index]</code>
 
 105           bevorzugt, wenn vorhanden. Ein Beispiel findet sich in SL/DO.pm,
 
 106           welches über alle Positionen eines Lieferscheins in Schleife
 
 107           läuft:</p><pre class="programlisting">for $i (1 .. $form->{rowcount}) {
 
 109   push @{ $form->{TEMPLATE_ARRAYS}{runningnumber} },   $position;
 
 110   push @{ $form->{TEMPLATE_ARRAYS}{number} },          $form->{"partnumber_$i"};
 
 111   push @{ $form->{TEMPLATE_ARRAYS}{description} },     $form->{"description_$i"};
 
 113 }</pre></div><div class="sect3" title="4.1.3.2. %::myconfig"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6446"></a>4.1.3.2. %::myconfig</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Das einzige Hash unter den globalen Variablen</p></li><li class="listitem"><p>Wird spätestens benötigt wenn auf die Datenbank
 
 114               zugegriffen wird</p></li><li class="listitem"><p>Wird bei jedem Request neu erstellt.</p></li><li class="listitem"><p>Enthält die Userdaten des aktuellen Logins</p></li><li class="listitem"><p>Sollte nicht ohne Filterung irgendwo gedumpt werden oder
 
 115               extern serialisiert werden, weil da auch der Datenbankzugriff
 
 116               für diesen user drinsteht.</p></li><li class="listitem"><p>Enthält unter anderem Listenbegrenzung vclimit,
 
 117               Datumsformat dateformat und Nummernformat numberformat</p></li><li class="listitem"><p>Enthält Datenbankzugriffinformationen</p></li></ul></div><p>
 
 118                   <code class="varname">%::myconfig</code> ist im Moment der Ersatz für
 
 119           ein Userobjekt. Die meisten Funktionen, die etwas anhand des
 
 120           aktuellen Users entscheiden müssen, befragen
 
 121           <code class="varname">%::myconfig</code>. Innerhalb der Anwendungen sind dies
 
 122           überwiegend die Daten, die sich unter <span class="guimenu">Programm</span>
 
 123           -> <span class="guimenuitem">Einstellungen</span> befinden, bzw. die
 
 124           Informationen über den Benutzer die über die
 
 125           Administrator-Schnittstelle eingegeben wurden.</p></div><div class="sect3" title="4.1.3.3. $::locale"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6485"></a>4.1.3.3. $::locale</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse "Locale"</p></li><li class="listitem"><p>Wird pro Request erstellt</p></li><li class="listitem"><p>Muss auch für Tests und Scripte immer verfügbar
 
 126               sein.</p></li><li class="listitem"><p>Cached intern über Requestgrenzen hinweg benutzte
 
 127               Locales</p></li></ul></div><p>Lokalisierung für den aktuellen User. Alle Übersetzungen,
 
 128           Zahlen- und Datumsformatierungen laufen über dieses Objekt.</p></div><div class="sect3" title="4.1.3.4. $::lxdebug"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6503"></a>4.1.3.4. $::lxdebug</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse "LXDebug"</p></li><li class="listitem"><p>Wird global gecached</p></li><li class="listitem"><p>Muss immer verfügbar sein, in nahezu allen
 
 129               Funktionen</p></li></ul></div><p>
 
 130                   <code class="varname">$::lxdebug</code> stellt Debuggingfunktionen
 
 131           bereit, wie "<code class="function">enter_sub</code>" und
 
 132           "<code class="function">leave_sub</code>", mit denen in den alten Modulen ein
 
 133           brauchbares Tracing gebaut ist, "<code class="function">log_time</code>", mit
 
 134           der man die Wallclockzeit seit Requeststart loggen kann, sowie
 
 135           "<code class="function">message</code>" und "<code class="function">dump</code>" mit
 
 136           denen man flott Informationen ins Log (tmp/kivitendo-debug.log)
 
 137           packen kann.</p><p>Beispielsweise so:</p><pre class="programlisting">$main::lxdebug->message(0, 'Meine Konfig:' . Dumper (%::myconfig));
 
 138 $main::lxdebug->message(0, 'Wer bin ich? Kunde oder Lieferant:' . $form->{vc});</pre></div><div class="sect3" title="4.1.3.5. $::auth"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6540"></a>4.1.3.5. $::auth</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse "SL::Auth"</p></li><li class="listitem"><p>Wird global gecached</p></li><li class="listitem"><p>Hat eine permanente DB Verbindung zur Authdatenbank</p></li><li class="listitem"><p>Wird nach jedem Request resettet.</p></li></ul></div><p>
 
 139                   <code class="varname">$::auth</code> stellt Funktionen bereit um die
 
 140           Rechte des aktuellen Users abzufragen. Obwohl diese Informationen
 
 141           vom aktuellen User abhängen wird das Objekt aus
 
 142           Geschwindigkeitsgründen nur einmal angelegt und dann nach jedem
 
 143           Request kurz resettet.</p><p>Dieses Objekt kapselt auch den gerade aktiven Mandanten.
 
 144           Dessen Einstellungen können über
 
 145           <code class="literal">$::auth->client</code> abgefragt werden; Rückgabewert
 
 146           ist ein Hash mit den Werten aus der Tabelle
 
 147           <code class="literal">auth.clients</code>.</p></div><div class="sect3" title="4.1.3.6. $::lx_office_conf"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6569"></a>4.1.3.6. $::lx_office_conf</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse
 
 148               "<code class="classname">SL::LxOfficeConf</code>"</p></li><li class="listitem"><p>Global gecached</p></li><li class="listitem"><p>Repräsentation der
 
 149               <code class="filename">config/kivitendo.conf[.default]</code>-Dateien</p></li></ul></div><p>Globale Konfiguration. Configdateien werden zum Start gelesen
 
 150           und danach nicht mehr angefasst. Es ist derzeit nicht geplant, dass
 
 151           das Programm die Konfiguration ändern kann oder sollte.</p><p>Beispielsweise ist über den Konfigurationseintrag [debug] die
 
 152           Debug- und Trace-Log-Datei wie folgt konfiguriert und
 
 153           verfügbar:</p><pre class="programlisting">[debug]
 
 154 file_name = /tmp/kivitendo-debug.log</pre><p>ist der Key <code class="varname">file</code> im Programm als
 
 155           <code class="varname">$::lx_office_conf->{debug}{file}</code>
 
 156           erreichbar.</p><div class="warning" title="Warnung" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Warning"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Warnung]" src="system/docbook-xsl/images/warning.png"></td><th align="left">Warnung</th></tr><tr><td align="left" valign="top"><p>Zugriff auf die Konfiguration erfolgt im Moment über
 
 157             Hashkeys, sind also nicht gegen Tippfehler abgesichert.</p></td></tr></table></div></div><div class="sect3" title="4.1.3.7. $::instance_conf"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6605"></a>4.1.3.7. $::instance_conf</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse
 
 158               "<code class="classname">SL::InstanceConfiguration</code>"</p></li><li class="listitem"><p>wird pro Request neu erstellt</p></li></ul></div><p>Funktioniert wie <code class="varname">$::lx_office_conf</code>,
 
 159           speichert aber Daten die von der Instanz abhängig sind. Eine Instanz
 
 160           ist hier eine Mandantendatenbank. Beispielsweise überprüft
 
 161           </p><pre class="programlisting">$::instance_conf->get_inventory_system eq 'perpetual'</pre><p>
 
 162           ob die berüchtigte Bestandsmethode zur Anwendung kommt.</p></div><div class="sect3" title="4.1.3.8. $::dispatcher"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6626"></a>4.1.3.8. $::dispatcher</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Objekt der Klasse
 
 163               "<code class="varname">SL::Dispatcher</code>"</p></li><li class="listitem"><p>wird pro Serverprozess erstellt.</p></li><li class="listitem"><p>enthält Informationen über die technische Verbindung zum
 
 164               Server</p></li></ul></div><p>Der dritte Punkt ist auch der einzige Grund warum das Objekt
 
 165           global gespeichert wird. Wird vermutlich irgendwann in einem anderen
 
 166           Objekt untergebracht.</p></div><div class="sect3" title="4.1.3.9. $::request"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6644"></a>4.1.3.9. $::request</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Hashref (evtl später Objekt)</p></li><li class="listitem"><p>Wird pro Request neu initialisiert.</p></li><li class="listitem"><p>Keine Unterstruktur garantiert.</p></li></ul></div><p>
 
 167                   <code class="varname">$::request</code> ist ein generischer Platz um
 
 168           Daten "für den aktuellen Request" abzulegen. Sollte nicht für action
 
 169           at a distance benutzt werden, sondern um lokales memoizing zu
 
 170           ermöglichen, das garantiert am Ende des Requests zerstört
 
 171           wird.</p><p>Vieles von dem, was im moment in <code class="varname">$::form</code>
 
 172           liegt, sollte eigentlich hier liegen. Die groben
 
 173           Differentialkriterien sind:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Kommt es vom User, und soll unverändert wieder an den
 
 174               User? Dann <code class="varname">$::form</code>, steht da eh schon</p></li><li class="listitem"><p>Sind es Daten aus der Datenbank, die nur bis zum Ende des
 
 175               Requests gebraucht werden? Dann
 
 176               <code class="varname">$::request</code>
 
 177                      </p></li><li class="listitem"><p>Muss ich von anderen Teilen des Programms lesend drauf
 
 178               zugreifen? Dann <code class="varname">$::request</code>, aber Zugriff über
 
 179               Wrappermethode</p></li></ul></div></div></div><div class="sect2" title="4.1.4. Ehemalige globale Variablen"><div class="titlepage"><div><div><h3 class="title"><a name="d0e6686"></a>4.1.4. Ehemalige globale Variablen</h3></div></div></div><p>Die folgenden Variablen waren einmal im Programm, und wurden
 
 180         entfernt.</p><div class="sect3" title="4.1.4.1. $::cgi"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6691"></a>4.1.4.1. $::cgi</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>war nötig, weil cookie Methoden nicht als
 
 181               Klassenfunktionen funktionieren</p></li><li class="listitem"><p>Aufruf als Klasse erzeugt Dummyobjekt was im
 
 182               Klassennamespace gehalten wird und über Requestgrenzen
 
 183               leaked</p></li><li class="listitem"><p>liegt jetzt unter
 
 184               <code class="varname">$::request->{cgi}</code>
 
 185                      </p></li></ul></div></div><div class="sect3" title="4.1.4.2. $::all_units"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6707"></a>4.1.4.2. $::all_units</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>war nötig, weil einige Funktionen in Schleifen zum Teil
 
 186               ein paar hundert mal pro Request eine Liste der Einheiten
 
 187               brauchen, und de als Parameter durch einen Riesenstack von
 
 188               Funktionen geschleift werden müssten.</p></li><li class="listitem"><p>Liegt jetzt unter
 
 189               <code class="varname">$::request->{cache}{all_units}</code>
 
 190                      </p></li><li class="listitem"><p>Wird nur in
 
 191               <code class="function">AM->retrieve_all_units()</code> gesetzt oder
 
 192               gelesen.</p></li></ul></div></div><div class="sect3" title="4.1.4.3. %::called_subs"><div class="titlepage"><div><div><h4 class="title"><a name="d0e6726"></a>4.1.4.3. %::called_subs</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>wurde benutzt um callsub deep recursions
 
 193               abzufangen.</p></li><li class="listitem"><p>Wurde entfernt, weil callsub nur einen Bruchteil der
 
 194               möglichen Rekursioenen darstellt, und da nie welche
 
 195               auftreten.</p></li><li class="listitem"><p>komplette recursion protection wurde entfernt.</p></li></ul></div></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s06.html">Zurück</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch04s02.html">Weiter</a></td></tr><tr><td width="40%" align="left" valign="top">3.6. Schweizer Kontenpläne </td><td width="20%" align="center"><a accesskey="h" href="index.html">Zum Anfang</a></td><td width="40%" align="right" valign="top"> 4.2. Entwicklung unter FastCGI</td></tr></table></div></body></html>