<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>/home/antu &#187; PHP</title>
	<atom:link href="http://www.antusblog.de/category/programmierung/php-programmierung/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.antusblog.de</link>
	<description>Linux, Programmierung und andere Dinge die mich interessieren</description>
	<lastBuildDate>Mon, 26 Oct 2009 06:00:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Der Trinitäts-Operator</title>
		<link>http://www.antusblog.de/2009/10/19/der-trinitats-operator/</link>
		<comments>http://www.antusblog.de/2009/10/19/der-trinitats-operator/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 11:08:37 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dreifach konditionaler Operator]]></category>
		<category><![CDATA[Fragezeichenoperator]]></category>
		<category><![CDATA[Ternary-Operator]]></category>
		<category><![CDATA[Trinitäts-Operator]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=2087</guid>
		<description><![CDATA[Der Trinitäts-Operator kann verwendet werden, um Zuweisungen/Funktionsaufrufe in Verbindung mit einer Bedingung bzw. Abfrage stark zu verkürzen. Richtig eingesetzt erhöht er die Lesbarkeit des Quelltextes und vermindert die Schreibarbeit. In diesem Artikel wird erklärt, wie der Trinitäts-Operator (engl. Ternary Operator, auch Fragezeichenoperator oder dreifach konditionaler Operator genannt) funktioniert, und wie man ihn richtig anwendet. Funktionsweise [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/?p=2087"><img class="alignright size-full wp-image-2100" title="Der Trinitaets Operator" src="http://www.antusblog.de/wp-content/uploads/2009/10/Der.Trinitaets-Operator.png" alt="Der Trinitaets Operator" width="150" height="150" /></a>Der Trinitäts-Operator kann verwendet werden, um Zuweisungen/Funktionsaufrufe in Verbindung mit einer Bedingung bzw. Abfrage stark zu verkürzen. Richtig eingesetzt erhöht er die Lesbarkeit des Quelltextes und vermindert die Schreibarbeit.</p>
<p>In diesem Artikel wird erklärt, wie der Trinitäts-Operator (engl. Ternary Operator, auch Fragezeichenoperator oder dreifach konditionaler Operator genannt) funktioniert, und wie man ihn richtig anwendet.</p>
<p><span id="more-2087"></span></p>
<h2>Funktionsweise</h2>
<p>Der Trinitäts-Operator stellt im Grunde eine Fallunterscheidung in Verbindung mit einer Zuweisung oder einem Funktionsaufruf dar. Man möchte einer Variablen entweder Wert 1, oder Wert 2 zuweisen, abhängig von einer Bedingung. Oder: Man möchte, abhängig von einer Bedingung entweder Funktion X oder Funktion Y aufrufen. Dadurch, dass man sich das <code>if/else</code> sparen kann, und den Variablennamen nur einmal schreiben muss, wird das ganze nicht nur kürzer, sondern auch übersichtlicher.</p>
<h3>Abfrage/Zuweisung mit if</h3>
<p>Würde man eine solche Zuweisung mit einer normalen <code>if/else</code>-Abfrage realisieren, bräuchte man 5 Zeilen. Das sähe wie folgt aus:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">if (&lt;Bedingung&gt;) {
    &lt;Variable&gt; = &lt;Wert 1&gt;;
} else {
    &lt;Variable&gt; = &lt;Wert 2&gt;;
}</pre></div></div>

<h3>Abfrage/Zuweisung mit if (verkürzt)</h3>
<p>Eine solche <code>if</code>-Abfrage lässt sich natürlich noch verkürzen. Die geschweiften Klammern können weggelassen werden, und man kann alles in eine Zeile quetschen.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">if (&lt;Bedingung&gt;) &lt;Variable&gt; = &lt;Wert 1&gt;; else &lt;Variable&gt; = &lt;Wert 2&gt;;</pre></div></div>

<h3>Abfrage/Zuweisung mit dem Trinitäts-Operator.</h3>
<p>Mit dem Trinitäts-Operator wird die Zuweisung dann noch kürzer, und wenn man den Trinitäts-Operator kennt, ist auch sofort ersichtlich, was diese Zeile tut.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&lt;Variable&gt; = (&lt;Bedingung&gt;) ? &lt;Wert 1&gt; : &lt;Wert 2&gt;;</pre></div></div>

<h3>Beispiel</h3>
<p>Und noch ein Beispiel, mit richtigen Werten.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Normale Form</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$antwort1</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$antwort2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1337</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Verkürzte Form</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$antwort1</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$antwort2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1337</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">else</span> <span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Trinitäts-Operator</span>
&nbsp;
<span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$antwort1</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$antwort2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1337</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span></pre></div></div>

<p>Man schreibt also zuerst die Bedingung (in Klammern), dann ein Fragezeichen und den Wert den die Variable annehmen soll, wenn die Bedingung wahr ist, dann einen Doppelpunkt, und den Wert für den Fall das die Bedingung unwahr ist.</p>
<h2>Noch kürzer</h2>
<p>Seit PHP 5.3 gibt es noch eine weitere Form des Trinitäts-Operators, mit der sich manche Zuweisungen noch weiter verkürzen lassen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>Variable<span style="color: #339933;">&gt;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">&lt;</span>Variable<span style="color: #339933;">/</span>Bedingung<span style="color: #339933;">&gt;</span> ?<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span>Wert<span style="color: #339933;">&gt;;</span></pre></div></div>

<p>Dabei wird <Variable/Bedingung> ausgewertet ob die Bedingung wahr ist, bzw. die Variable den booleschen Wert <code>true</code> hat (oder dazu umgewandelt werden kann). Ist das der Fall, bekommt die Variable den Wert der Bedingung zugewiesen, ansonsten den anderen Wert.</p>
<p>Hier noch ein Beispiel, welches das ganze vielleicht etwas besser verdeutlicht: </p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> ?<span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></div></div>

<p>Wenn <code>$_GET['id']</code> gesetzt, und ungleich <code>0</code> ist, nimmt <code>$id</code> den Wert von <code>$_GET['id']</code> an. Ansonsten bekommt <code>$id</code> den Wert <code>0</code>. Das <code>@</code> steht da, damit PHP nicht über eine undeklarierte Variable meckert, falls <code>$_GET['id']</code> nicht gesetzt ist.</p>
<h2>Funktionen aufrufen</h2>
<p>Der Trinitäts-Operator kann auch in Verbindung mit Funktionsaufrufen verwendet werden. Dabei ist es auch möglich mehrere Funktionen aufzurufen. Von letzterem rate ich allerdings ab, in den meisten Fällen wird das schnell unübersichtlich. Wie es funktioniert erkläre ich allerdings trotzdem: Um mehrere Funktionen im Trinitäts-Operator zu verwenden, müssen diese mittels <code>AND</code> verbunden werden, eine Trennung mittels Semikolon oder <code>&#038;&#038;</code> funktioniert nicht.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$allesrichtig</span> ? <span style="color: #b1b100;">print</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Alle Fragen wurden richtig beantwortet, super!&quot;</span><span style="color: #009900;">&#41;</span> AND
                <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Das Quiz ist zu Ende.&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Leider falsch!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Es ist übrigens auch möglich, den Trinitätsoperator innerhalb von Zeichenketten zu verwenden:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Bitte '</span> <span style="color: #339933;">.</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$siezen</span> ? <span style="color: #0000ff;">'klicken Sie '</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'klicke '</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'hier, '</span>
<span style="color: #339933;">.</span> <span style="color: #0000ff;">'um zur vorherigen Seite zurückzukehren'</span><span style="color: #339933;">;</span></pre></div></div>

<h2>So nicht!</h2>
<p>Der Trinitäts-Operator kann zwar verschachtelt werden, davon rate ich aber ab. Solche Zuweisungen werden schnell sehr unübersichtlich.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Unübersichtlich:</span>
<span style="color: #000088;">$allesrichtig</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$antwort1</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$antwort2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1337</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$antwort3</span> <span style="color: #339933;">&gt;</span> <span style="color: #000088;">$antwort4</span><span style="color: #009900;">&#41;</span> ?
                <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Beispiel-Datei</h2>
<p>Eine Beispieldatei, mit allen möglichen Formen der Verwendung des Trinitäts-Operators habe ich auch noch erstellt: <a href="/demos/11-der-trinitaets-operator/Beispiel.phps">Beispiel.phps</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/10/19/der-trinitats-operator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Der Alternative PHP Cache</title>
		<link>http://www.antusblog.de/2009/08/12/der-alternative-php-cache/</link>
		<comments>http://www.antusblog.de/2009/08/12/der-alternative-php-cache/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:56:50 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Alternative PHP Cache]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[optimieren]]></category>
		<category><![CDATA[Zwischenspeicher]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1677</guid>
		<description><![CDATA[Der Alternative PHP Cache ist ein quelloffenes PHP-Modul, das die Ausführung des Quelltextes beschleunigt und eine Zwischenspeicherung von Daten ermöglicht. Der APC legt den kompilierten Code der aus einem PHP-Quelltext normalerweise beim jedem Aufruf erstellt wird in einem Zwischenspeicher ab, wodurch der zeitaufwendige Prozess des Kompilierens beim Aufrufen der Datei entfällt. Außerdem können Variablen und [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/08/APC.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/08/APC.png" alt="APC" title="APC" width="500" height="200" class="aligncenter size-full wp-image-1919" /></a><br />
Der Alternative PHP Cache ist ein quelloffenes PHP-Modul, das die Ausführung des Quelltextes beschleunigt und eine Zwischenspeicherung von Daten ermöglicht. Der APC legt den kompilierten Code der aus einem PHP-Quelltext normalerweise beim jedem Aufruf erstellt wird in einem Zwischenspeicher ab, wodurch der zeitaufwendige Prozess des Kompilierens beim Aufrufen der Datei entfällt. Außerdem können Variablen und Objekte im Zwischenspeicher gelagert werden, wodurch diese auch über mehrere Aufrufe hinweg verfügbar sind.</p>
<p><span id="more-1677"></span></p>
<h2>Geschwindigkeitsvergleich</h2>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/07/APC.Artikel.von.Dominik.Deobald.png"><img class="alignright size-full wp-image-1732" title="Dominik Deobald vergleicht in seinem Artikel verschiedene Zwischenspeicher." src="http://www.antusblog.de/wp-content/uploads/2009/07/APC.Artikel.von.Dominik.Deobald.png" alt="Dominik Deobald vergleicht in seinem Artikel verschiedene Zwischenspeicher." width="150" height="150" /></a>Dominik Deobald vergleicht in seinem Artikel <a href="http://blogs.interdose.com/dominik/2008/04/11/benchmarking-php-eaccelerator-und-andere-opcode-caches/">Benchmarking PHP: eAccelerator und andere OpCode Caches</a> die Geschwindigkeit von PHP ohne Zwischenspeicher mit der Geschwindigkeit von 5 populären Zwischenspeichern. Neben APC werden auch eAccelerator, Zend und xCache getestet. Sein Fazit: Die Nutzung eines Zwischenspeichers lohnt sich, wie sehr die Geschwindigkeit sich verbessern lässt ist allerdings anwendungsabhängig. In seinen Tests schneidet der <a href="http://eaccelerator.net/">eAccelerator</a> etwas besser ab als APC.</p>
<h2>Installation von APC</h2>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/APC.in.der.phpinfo.png"><img class="alignright size-thumbnail wp-image-1573" title="In der Ausgabe von phpinfo() findet sich auch ein Abschnitt über APC" src="http://www.antusblog.de/wp-content/uploads/2009/06/APC.in.der.phpinfo-150x150.png" alt="In der Ausgabe von phpinfo() findet sich auch ein Abschnitt über APC" width="150" height="150" /></a>Ab PHP 6 soll APC zu PHP standardmäßig dazugehören, zur Zeit ist es nur ein PECL-Modul, und muss erst installiert werden. Die meisten Linux-Distributionen bieten allerdings Pakete für APC an, was die Installation stark vereinfacht. Aber auch die Installation mittels PECL ist eigentlich nicht weiter schwer. Wie man den Zwischenspeicher installiert, und ihn in der <code>php.ini</code> aktiviert, erkläre ich im Artikel <a href="http://www.antusblog.de/?p=1508">Installation von APC</a>.</p>
<h2>APC richtig konfigurieren</h2>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Konfiguration.png"><img class="alignright size-thumbnail wp-image-1579" title="Konfiguration von APC" src="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Konfiguration-150x130.png" alt="Konfiguration von APC" width="150" height="130" /></a>Die Standardkonfiguration von APC ist für die meisten Einsatzzwecke gut geeignet. Dennoch gibt es einige Optionen, die man vielleicht anpassen möchte. In meinem Artikel <a href="http://www.antusblog.de/?p=1669">Konfiguration von APC</a> erkläre ich die wichtigsten Optionen, und zeige eine Übersicht aller Einstellungsmöglichkeiten. Ich beschreibe beispielsweise wie man die Größe des Zwischenspeichers verändern kann, wie die Überwachung des Hochladevorgangs eingeschaltet wird, die Lebensdauer von Dateien im Zwischenspeicher eingestellt wird, und noch einiges mehr.</p>
<h2>Funktionen von APC</h2>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/07/APC.Quelltext.png"><img class="alignright size-full wp-image-1740" title="Quelltext" src="http://www.antusblog.de/wp-content/uploads/2009/07/APC.Quelltext.png" alt="Quelltext" width="150" height="150" /></a>APC kann nicht nur die Geschwindigkeit von PHP erhöhen, indem es vorkompilierte Dateien zwischenspeichert. APC kann auch Variablen/Konstanten/Objekte im Zwischenspeicher ablegen, und diese über mehrere Aufrufe hinweg verfügbar machen. So können beispielsweise zeitaufwendige Datenbankabfragen eingespart werden. Außerdem bietet APC einige nützliche Funktionen, die einem nützliche Informationen über den Zwischenspeicher liefern, sowie die Möglichkeit geben Dateien/Variablen aus ihm zu entfernen. Welche Funktionen es gibt, und wie man sie benutzt, beschreibe ich im Artikel <a href="http://www.antusblog.de/?p=1686">Funktionen von APC</a>.</p>
<h2>APC überwachen</h2>
<div style="clear:both;"><a href="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Statistiken.png"><img class="alignright size-thumbnail wp-image-1598" title="Statistiken über die Speicherauslastung sowie die Trefferquote des Zwischenspeichers" src="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Statistiken-150x150.png" alt="Statistiken über die Speicherauslastung sowie die Trefferquote des Zwischenspeichers" width="150" height="150" /></a>Mit APC wird noch ein kleines PHP-Skript mitgeliefert, mit dem man den Zustand des Zwischenspeichers überwachen kann. Außerdem können damit im Zwischenspeicher gespeicherte Variablen und Dateien eingesehen und auch gelöscht werden. Wie dieses Skript benutzt wird, erkläre ich in meinem Artikel <a href="http://www.antusblog.de/?p=1667">APC: Status und Überwachung</a>.</div>
<div style="clear:both;">
<h2>Fortschrittsanzeige beim Hochladen von Dateien</h2>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/08/Fortschrittsbalken.APC.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/08/Fortschrittsbalken.APC-150x150.png" alt="Ein roter Fortschrittsbalken" title="Ein roter Fortschrittsbalken" width="150" height="150" class="alignright size-thumbnail wp-image-1856" /></a>Mithilfe von APC ist es möglich Informationen über den Hochladevorgang von Dateien zu ermitteln, mit diesen Informationen lässt sich der Fortschritt anzeigen, beispielsweise in Form eines Fortschrittsbalkens. Wie das geht, beschreibe ich im Artikel <a href="http://www.antusblog.de/?p=1849">Fortschrittsanzeige beim Hochladen von Dateien</a>.</div>
<h2>Alternativen</h2>
<p>APC ist nicht der einzige Zwischenspeicher für PHP, es gibt noch einige andere. Einer davon ist <a href="http://xcache.lighttpd.net/">XCache</a>, der übrigens wie APC neben dem Zwischenspeicher für vorkompilierte Dateien noch über einen Variablen-Zwischenspeicher verfügt. Außerdem gibt es noch den <a href="http://eaccelerator.net/">eAccelerator</a>, und den <a href="http://www.zend.com/products/server/">Zend Cache</a>. Der IonCube PHP Accelerator und TurkMMCache sind ebenfalls Zwischenspeicher, diese werden allerdings schon seit längerer Zeit nicht mehr weiterentwickelt, und funktionieren nicht mehr mit neueren PHP-Versionen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/08/12/der-alternative-php-cache/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Funktionen von APC</title>
		<link>http://www.antusblog.de/2009/08/12/funktionen-von-apc/</link>
		<comments>http://www.antusblog.de/2009/08/12/funktionen-von-apc/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:47:24 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Alternative PHP Cache]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Funktionen]]></category>
		<category><![CDATA[Zwischenspeicher]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1686</guid>
		<description><![CDATA[APC kann nicht nur Dateien vorkompilieren und zwischenspeichern, sondern auch Variablen und Konstanten in einem Zwischenspeicher ablegen, und sie somit über mehrere Aufrufe hinweg verfügbar machen. Neben dem Auslesen, Speichern und Löschen von Variablen, Objekten und Konstanten, gibt es noch die Möglichkeit Informationen über den Zustand des Zwischenspeichers und darin gespeicherten Daten herauszufinden. Außerdem gibt [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/07/Funktionen.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/07/Funktionen.png" alt="Funktionen" title="Funktionen" width="500" height="200" class="aligncenter size-full wp-image-1909" /></a>APC kann nicht nur Dateien vorkompilieren und zwischenspeichern, sondern auch Variablen und Konstanten in einem Zwischenspeicher ablegen, und sie somit über mehrere Aufrufe hinweg verfügbar machen. Neben dem Auslesen, Speichern und Löschen von Variablen, Objekten und Konstanten, gibt es noch die Möglichkeit Informationen über den Zustand des Zwischenspeichers und darin gespeicherten Daten herauszufinden. Außerdem gibt es noch eine Funktion, die den Zwischenspeicher leert.</p>
<p><span id="more-1686"></span></p>
<h2>Variablen und Objekte</h2>
<p>Variablen, Objekte und Konstanten werden im sog. User Cache abgelegt, dabei muss ihnen ein einzigartiger Schlüssel zugewiesen werden. APC stellt Funktionen zum Speichern, Auslesen, Überschreiben und Löschen bereit. Bei Variablen und Objekten lässt sich eine Lebensdauer angeben, diese wird bei jedem Aufruf überprüft, wurde sie überschritten, wird die Variable aus dem Zwischenspeicher gelöscht. Hat die Lebensdauer den Wert 0 (Standard), ist sie unendlich, die Variable wird also nicht automatisch gelöscht (außer natürlich bei einem Neustart/Leeren des Zwischenspeichers).</p>
<p>Hinweis: Es ist nicht möglich, ein Feld von Objekten im Zwischenspeicher abzulegen. Das Feld wird zwar gespeichert, die darin befindlichen Objekte haben aber alle den Wert <code>NULL</code>. Es gibt allerdings einen Weg, trotzdem ein Feld von Objekten zu speichern, und zwar mit dem <code><a href="http://de3.php.net/manual/de/function.apc-store.php#73560">ArrayObject</a></code>.</p>
<h3>Speichern von Variablen/Objekten</h3>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_add(string Schlüssel, mixed Variable
             [, int Lebensdauer = 0])
bool apc_store(string Schlüssel, mixed Variable
               [, int Lebensdauer = 0])</pre></div></div>

<p>Diese Funktionen speichern eine Variable bzw. ein Objekt im Zwischenspeicher, der erste Parameter ist der Schlüssel/Name unter dem diese abgelegt wird. Der zweite Parameter ist die Variable selbst, der dritte (optional) gibt die Lebensdauer an. Die Funktion <code><a href="http://php.net/manual/de/function.apc-store.php">apc_store</a></code> überschreibt eine Variable, wenn der Schlüssel bereits vorhanden ist, <code><a href="http://php.net/manual/de/function.apc-add.php">apc_add</a></code> gibt in diesem Fall <code>false</code> zurück, ohne die Variable zu überschreiben.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// true (wenn die Variable noch nicht im Zwischenspeicher ist)</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>apc_add<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hallo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Hallo Welt'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// false, da der Schlüssel 'hallo' bereits existiert.</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>apc_add<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hallo'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">123</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hallo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Hallo Welt</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// apc_store überschreibt die Variable, wenn der Schlüssel bereits</span>
<span style="color: #666666; font-style: italic;">// existiert.</span>
apc_store<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hallo'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">456</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hallo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 456</span></pre></div></div>

<h3>Auslesen von Variablen/Objekten</h3>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">mixed apc_fetch(string Schlüssel [, bool &amp;Erfolg])
array apc_fetch(array Schlüssel [, bool &amp;Erfolg])</pre></div></div>

<p>Mit <code><a href="http://de.php.net/apc_fetch">apc_fetch</a></code> können die Daten wieder aus dem Zwischenspeicher ausgelesen werden. Der erste Parameter ist der Schlüssel, unter dem die Variable abgelegt ist. Die ausgelesenen Daten werden zurückgegeben, konnten keine Daten ausgelesen werden (z.B. weil der Schlüssel nicht existiert) wird <code>false</code> zurückgegeben.</p>
<p>Im zweiten Parameter kann eine Referenz auf eine Variable angegeben werden, die von APC bei erfolgreichem Auslesen auf <code>true</code>, ansonsten auf <code>false</code> gesetzt wird. Das ist ganz nützlich, da man ja auch Variablen vom Typ <code>boolean</code> (<code>true</code> oder <code>false</code>) im Zwischenspeicher ablegen kann, und man sonst nicht herausfinden könnte, ob der Rückgabewert <code>false</code> nun bedeutet das die Variable den Wert <code>false</code> hat, oder die Variable nicht ausgelesen werden konnte.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">apc_store<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Test'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">123</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Inhalt von 'Test': &quot;</span><span style="color: #339933;">,</span> apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Test'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 123</span>
<span style="color: #000088;">$erfolg</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Inhalt von 'ExistiertNicht': &quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ExistiertNicht'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$erfolg</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// false</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'$erfolg: '</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$erfolg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// false</span></pre></div></div>

<p>Es ist auch möglich mehrere Schlüssel auf einmal abzufragen, dazu übergibt man anstatt eines Schlüssels einfach ein Feld mit mehreren Schlüsseln.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Test'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hallo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>APC gibt dann ein Feld (Schlüssel =&gt; Wert) zurück. Wenn einer der Schlüssel ausgelesen werden konnte, gilt die Abfrage als erfolgreich, konnte kein Schlüssel ausgelesen werden, wird ein leeres Feld zurückgegeben, und <code>$Erfolg</code> ist trotzdem <code>true</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">array(2) { [&quot;Test&quot;]=&gt;  int(123)
           [&quot;hallo&quot;]=&gt;  int(456)
}</pre></div></div>

<h3>Löschen von Variablen/Objekten</h3>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_delete(string Schlüssel)</pre></div></div>

<p>Mit <code><a href="http://de3.php.net/manual/de/function.apc-delete.php">apc_delete</a></code> können Variablen/Objekte wieder aus dem Zwischenspeicher gelöscht werden.</p>
<h2>Konstanten</h2>
<p>Mit der Funktion <code><a href="http://php.net/manual/de/function.apc-define-constants.php">apc_define_constants</a></code> lässt sich ein Satz von Konstanten im Zwischenspeicher speichern. Mittels <code><a href="http://php.net/manual/de/function.apc-load-constants.php">apc_load_constants</a></code> kann dieser wieder ausgelesen werden. Jeder Satz von Konstanten bekommt einen Namen, es ist also auch möglich mehrere verschiedene Sätze von Konstanten zu speichern.</p>
<p>Das erstmalige Definieren der Konstanten, bzw. deren Eintragung im Zwischenspeicher dauert etwa doppelt so lange, als würde man <code><a href="http://php.net/define">define</a></code> verwenden, das Laden der Konstanten aus dem Zwischenspeicher ist allerdings drei mal so schnell wie <code>define</code>. Anschließend können die Konstanten verwendet werden, wie sonst auch.</p>
<h3>Definieren von Konstanten</h3>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_define_constants(string Schlüssel, array Konstanten
                          [, bool Groß- u. Kleinschreibung beachten = true])</pre></div></div>

<p>Die Funktion <code><a href="http://php.net/manual/de/function.apc-define-constants.php">apc_define_constants</a></code> erwartet zwei Parameter. Der erste ist der Name/Schlüssel unter dem der Satz von Konstanten gespeichert wird, der zweite ist ein Feld, welches die Konstanten enthält. Der dritte Parameter ist optional, und gibt an ob bei den Konstantennamen die Groß- und Kleinschreibung beachtet werden soll (also ob <code>KONSTANTE</code> und <code>Konstante</code> ein und die selbe Konstante sind (false) oder nicht (true)).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$konstanten</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ROT'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'#f00'</span><span style="color: #339933;">,</span>
                     <span style="color: #0000ff;">'GRUEN'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'#0f0'</span><span style="color: #339933;">,</span>
                     <span style="color: #0000ff;">'BLAU'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'#00f'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
apc_define_constants<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'farben'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$konstanten</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bei Erfolg gibt die Funktion <code>true</code> zurück, ansonsten <code>false</code>.</p>
<h3>Konstanten auslesen</h3>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_load_constants(string Schlüssel
                        [, bool Groß- u. Kleinschreibung beachten = true])</pre></div></div>

<p>Mit <a href="http://php.net/manual/de/function.apc-load-constants.php"><code>apc_load_constants</code></a> können die gespeicherten Konstanten wieder ausgelesen werden, sie werden beim Auslesen automatisch definiert. Der erste Parameter gibt wieder den Schlüssel/Namen des Konstantensatzes an, der zweite, optionale Parameter, gibt an ob die Groß- und Kleinschreibung beachtet wird. Bei Erfolg wird <code>true</code>, ansonsten <code>false</code> zurückgegeben.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">apc_load_constants<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'farben'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Rot: &quot;</span><span style="color: #339933;">,</span> ROT<span style="color: #339933;">;</span></pre></div></div>

<h3>Konstanten aus dem Zwischenspeicher entfernen</h3>
<p>Um einen Satz von Konstanten wieder zu entfernen, kann die Funktion <code>apc_delete</code> verwendet werden.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">apc_delete<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'farben'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Informationen über den Zwischenspeicher</h2>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">array apc_cache_info([string Typ[, bool Limitiert]])
array apc_sma_info([bool Limitiert])</pre></div></div>

<p>Die Funktion <code><a href="http://us3.php.net/manual/en/function.apc-cache-info.php">apc_cache_info</a></code> kann verwendet werden, um Informationen über den Zwischenspeicher und darin enthaltene Dateien, Variablen, etc. zu erhalten. Der <code>Typ</code> gibt an, welche Art von Informationen zurückgegeben werden soll. Der Parameter <code>Limitiert</code> bestimmt, ob nur generelle Informationen (<code>true</code>) oder auch ein Feld mit Informationen über die einzelnen Dateien/Variablen (<code>false</code>) zurückgegeben werden soll.</p>
<p>Folgende Typen stehen zur Verfügung:</p>
<ul>
<li><a href="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_user.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_user-150x150.png" alt="Beispielausgabe von apc_cache_info(&#039;user&#039;);" title="Beispielausgabe von apc_cache_info(&#039;user&#039;);" width="150" height="150" class="alignright size-thumbnail wp-image-1755" /></a><code>"user"</code>: Informationen über den &#8220;User Cache&#8221;, also die Anzahl der gespeicherten Variablen, noch freie (verfügbare) Einträge, wie oft Variablen gespeichert wurden, wie viel Speicher die Variablen verbrauchen, etc. Ist die Ausgabe nicht limitiert, werden auch noch ausführliche Informationen über jede einzelne Variable zu dem Feld hinzugefügt.</li>
<li style="clear:both"><a href="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_filehits.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_filehits-150x150.png" alt="Beispielausgabe von apc_cache_info(&#039;user&#039;);" title="Beispielausgabe von apc_cache_info(&#039;user&#039;);" width="150" height="150" class="alignright size-thumbnail wp-image-1758" /></a><code>"filehits"</code>: Eine Liste von Dateien die für den aktuellen Aufruf aus dem Zwischenspeicher geholt wurden. (Funktioniert nur, wenn <code>--enable-apc-filehits</code> bei der Installation angegeben wurde.)</li>
<li style="clear:both"><a href="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_system.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/07/apc_cache_info_system-150x150.png" alt="Beispielausgabe von apc_cache_info();" title="Beispielausgabe von apc_cache_info();" width="150" height="150" class="alignright size-thumbnail wp-image-1760" /></a>Datei-Speicher: Wenn kein Typ oder ein ungültiger Typ angegeben wurde, gibt die Funktion Informationen über den Dateispeicher zurück. Zum Beispiel die Größe des Speichers, die Anzahl der Dateien, wie oft eine Datei nicht im Cache gefunden wurde, etc. Wenn die Ausgabe nicht limitiert ist, wird auch ein Feld mit Informationen über alle gespeicherten Dateien zurückgeliefert.</li>
</ul>
<p style="clear:both"><a href="http://www.antusblog.de/wp-content/uploads/2009/07/apc_sma_info.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/07/apc_sma_info-150x150.png" alt="Beispielausgabe von apc_sma_info();" title="Beispielausgabe von apc_sma_info();" width="150" height="150" class="alignright size-thumbnail wp-image-1767" /></a>Die Funktion <a href="http://de2.php.net/manual/en/function.apc-sma-info.php"><code>apc_sma_info</code></a> hingegen liefert Informationen über den benutzten Speicher. Sie gibt ein Feld zurück, mit Informationen darüber wie viele Segmente verwendet werden, wie groß diese sind, und wie viel Speicher insgesamt zur Verfügung steht. Ist die Ausgabe nicht limitiert, werden auch noch Informationen über die einzelnen Segmente zurückgegeben.</p>
<h2>Zwischenspeicher leeren</h2>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_clear_cache([string Typ])</pre></div></div>

<p>Um den Zwischenspeicher zu leeren, kann die Funktion <code>apc_clear_cache</code> verwendet werden. Hat der Parameter den Wert <code>user</code>, wird der Variablen/Objekte/Konstanten-Zwischenspeicher geleert, ansonsten wird der Zwischenspeicher für Dateien geleert. Gibt <code>true</code> bei Erfolg zurück, ansonsten <code>false</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">apc_clear_cache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Datei kompilieren und zwischenspeichern</h2>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">bool apc_compile_file(string Dateiname)</pre></div></div>

<p>Mit <a href="http://de.php.net/manual/de/function.apc-compile-file.php">apc_compile_file</a> wird eine Datei kompiliert und im Zwischenspeicher gespeichert. In der Konfiguration eingestellte Filter werden dabei umgangen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>apc_compile_file<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'datei.php'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Datei &gt;datei.php&lt; wurde im Zwischenspeicher abgelegt.&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Fehler: Datei konnte nicht im Zwischenspeicher abgelegt werden.&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Die Funktion gibt bei Erfolg <code>true</code>, im Fehlerfall <code>false</code> zurück.</p>
<h2>Überprüfen ob APC verfügbar ist</h2>
<p>Wenn man überprüfen möchte, ob APC verfügbar ist, kann man mit <code>extension_loaded</code> einfach überprüfen ob die Erweiterung geladen ist. Wenn APC geladen ist, gibt die Funktion <code>true</code> zurück, ansonsten <code>false</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apc'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// true oder false</span></pre></div></div>

<p><em>Es gibt noch ein paar andere APC-Funktionen, wie beispielsweise <code>apc_inc</code>/<code>apc_dec</code>, diese sind allerdings leider (noch) nicht dokumentiert, weswegen ich diese hier nicht erklären werde. </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/08/12/funktionen-von-apc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fortschrittsanzeige beim Hochladen von Dateien</title>
		<link>http://www.antusblog.de/2009/08/12/fortschrittsanzeige-beim-hochladen-von-dateien/</link>
		<comments>http://www.antusblog.de/2009/08/12/fortschrittsanzeige-beim-hochladen-von-dateien/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:29:20 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[Java Script]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Alternative PHP Cache]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Dateien]]></category>
		<category><![CDATA[Fortschrittsanzeige]]></category>
		<category><![CDATA[Fortschrittsbalken]]></category>
		<category><![CDATA[hochladen]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1849</guid>
		<description><![CDATA[Das Hochladen von Dateien kann unter Umständen sehr lange, manchmal sogar Stunden dauern. Normalerweise gibt der Browser dem Benutzer aber keine Rückmeldung darüber, wie viele Daten schon hochgeladen wurden, bzw. wie lange der Vorgang noch dauern wird. Mit APC lassen sich während des Hochladevorgangs Informationen über selbigen ermitteln, und diese können benutzt werden um eine [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/08/Fortschrittsbalken.APC.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/08/Fortschrittsbalken.APC.png" alt="Ein roter Fortschrittsbalken" title="Ein roter Fortschrittsbalken" width="500" height="200" class="aligncenter size-full wp-image-1856" /></a>Das Hochladen von Dateien kann unter Umständen sehr lange, manchmal sogar Stunden dauern. Normalerweise gibt der Browser dem Benutzer aber keine Rückmeldung darüber, wie viele Daten schon hochgeladen wurden, bzw. wie lange der Vorgang noch dauern wird. Mit APC lassen sich während des Hochladevorgangs Informationen über selbigen ermitteln, und diese können benutzt werden um eine Fortschrittsanzeige für den Benutzer zu erstellen. Der Fortschritt könnte beispielsweise als Prozentwert, als Balken, oder als absoluter Wert (123/567 MiB) angezeigt werden. Eine Fortschrittsanzeige beim Hochladen steigert die Benutzerfreundlichkeit der Seite.</p>
<p>Wie man diese Funktionalität von APC benutzt, was vorausgesetzt wird, und welches Informationen APC liefern kann erkläre ich in diesem Artikel.</p>
<p><span id="more-1849"></span></p>
<h2>Voraussetzungen</h2>
<p>Um den Hochladevorgang mittels APC zu überwachen, bzw. Informationen über ihn zu erhalten, werden einige Dinge vorausgesetzt. Natürlich muss <strong>APC installiert und aktiviert</strong> sein. In der <a href="http://www.antusblog.de/?p=1669">APC-Konfiguration</a> muss die Option <strong><code>apc.rfc1867</code> auf <code>On</code></strong> stehen. Der Benutzer muss <strong>JavaScript</strong> in seinem Browser aktiviert haben, denn sonst kann der Fortschritt nicht mittels <strong>AJAX</strong> abgefragt werden. Außerdem muss das Hochlade-Formular um ein weiteres <strong><code>input</code>-Element</strong> erweitert werden. Als Ziel-Adresse für das Formular wird ein <strong><code>iframe</code></strong> verwendet.</p>
<p>Die Werte folgender beider APC-Optionen müssen bekannt sein:</p>
<ul>
<li>Der Präfix: <code>apc.rfc1867_prefix</code> (<code>upload_</code>)</li>
<li>Der Name des Formularelements: <code>apc.rfc1867_name</code> (<code>APC_UPLOAD_PROGRESS</code>)</li>
</ul>
<p>(Standardwerte in Klammern, wenn nichts an der Konfiguration geändert wurde, kann man davon ausgehen das APC diese Werte verwendet. Der Einfachheit halber verwende ich in dieser Anleitung in Beispielen immer die Standardwerte, wenn man andere Werte benutzt, müssen diese natürlich entsprechend angepasst werden.)</p>
<h2>Das Formular</h2>
<p>Das Hochlade-Formular muss etwas erweitert werden. Zuerst wird ein zusätzliches <code>input</code>-Element mit dem Namen <code>APC_UPLOAD_PROGRESS</code> erstellt, welches einen eindeutigen Wert zugewiesen bekommt. Über diesen Wert kann später der Hochladevorgang verfolgt werden, deshalb ist es auch wichtig, dass der Wert einzigartig ist, sonst funktioniert das ganze nicht mehr, wenn mehrere Benutzer gleichzeitig Dateien hochladen. Mit der PHP-Funktion <code><a href="http://de3.php.net/uniqid">uniqid()</a></code> ist das aber kein Problem, sie erstellt eindeutige IDs.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;APC_UPLOAD_PROGRESS&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php echo uniqid(); ?&gt;</span></span>&quot; /&gt;</pre></div></div>

<p>Wenn eine Datei hochgeladen wird, blockiert die Seite normalerweise, und der Benutzer kann nichts auf der Seite machen, bis die Datei vollständig hochgeladen wurde. Ist die Datei dann hochgeladen, bekommt der Benutzer die Ausgabe der Ziel-Seite (<code>action</code>) des Formulars zu sehen. Wenn man eine Fortschrittsanzeige erstellen möchte ist das natürlich ungünstig. Deshalb erstellt man ein <code>iframe</code>, und weist dem Formular dieses <code>iframe</code> als <code>target</code> zu. Dadurch wird die Ziel-Seite im <code>iframe</code> geladen, und die Formular-Seite blockiert nicht.</p>
<p>Das sollte man aber nur machen, wenn der Benutzer JavaScript aktiviert hat, und somit die Fortschrittsanzeige sehen kann. Deswegen wird die <code>target</code>-Eigenschaft dem Formular per JavaScript zugewiesen. Hat der Benutzer JavaScript deaktiviert, verhält sich das Formular wie jedes andere auch (ohne Fortschrittsanzeige, aber mit Blockieren), ist JavaScript aktiviert sieht der Benutzer die Fortschrittsanzeige und die Seite blockiert nicht.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">iframe</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;upload.php&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;versteckt&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none;&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">iframe</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dateihochladen&quot;</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;upload.php&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>document.forms.dateihochladen.target = 'versteckt';<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<p>Fehlt nur noch der AJAX-Teil des ganzen. Vorher benötigt man allerdings noch eine PHP-Datei, die die Informationen über den Vorgang liefert.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'upload_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Mittels <code>apc_fetch</code> werden die Informationen aus dem Zwischenspeicher ausgelesen, hierzu wird die eindeutige ID benötigt, welche man praktischerweise einfach über die URL überträgt und mittels <code>$_GET</code> abfragt. Anstatt das komplette Feld mit allen Informationen per <code>var_dump</code> auszugeben, kann man es natürlich auch per <code>json_encode</code> umwandeln (und dann gleich im JavaScript weiterverwenden), oder per PHP gleich die Fortschrittsanzeige in HTML ausgeben. Aber das ist jedem selbst überlassen.</p>
<p>Der AJAX-Teil ist auch nicht weiter schwer, man ruft einfach nach dem Absenden des Formulars in bestimmten Zeitintervallen die obige PHP-Datei ab, und verarbeitet die Informationen weiter, bzw. gibt sie aus. Komplett sieht das ganze dann so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">                      &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span> <span style="color: #000066;">dir</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ltr&quot;</span> <span style="color: #000066;">lang</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;de-DE&quot;</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>Fortschrittsanzeige beim Hochladen von Dateien<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
    function aktualisiere() {
      var anfrage = null;
&nbsp;
      if (window.XMLHttpRequest) {
        anfrage = new XMLHttpRequest();
      }
      else if (window.ActiveXObject) {
        anfrage = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
      }
&nbsp;
      anfrage.onreadystatechange = function() {
       if ((anfrage.readyState == 4) <span style="color: #ddbb00;">&amp;&amp; (anfrage.status == 200)) {</span>
<span style="color: #ddbb00;">          document.getElementById('status').innerHTML = anfrage.responseText;</span>
        }
      }
&nbsp;
      anfrage.open('GET', 'status.php?id=' + 
                    document.forms.dateihochladen.APC_UPLOAD_PROGRESS.value);
      anfrage.send(null);
    }
&nbsp;
    function ladeHoch(elem) {
      elem.disabled = true;
&nbsp;
      setInterval('aktualisiere()', 1000);
    }
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stil.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>Dateien hochladen mit Fortschrittsanzeige<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;inhalt&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">iframe</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;versteckt&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none;&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">iframe</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dateihochladen&quot;</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;upload.php&quot;</span> </span>
<span style="color: #009900;">            <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
        document.forms.dateihochladen.target = 'versteckt';
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">fieldset</span>&gt;</span>
          <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">legend</span>&gt;</span>Datei<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">legend</span>&gt;</span>
          <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;APC_UPLOAD_PROGRESS&quot;</span> </span>
<span style="color: #009900;">                 <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php echo uniqid(); ?&gt;</span></span>&quot; /&gt;
          <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;datei&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
          <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Hochladen&quot;</span> </span>
<span style="color: #009900;">                 <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ladeHoch(this);&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">fieldset</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;status&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></div></div>

<p>In der Form funktioniert das Skript bereits, es macht aber nichts anderes, als das von APC zurückgegebene Feld mit Informationen im <code>status-div</code> auszugeben. </p>
<h2>Welche Informationen bekommt man?</h2>
<p>Welche Informationen APC zurückgibt hängt davon ab, ob die Datei gerade hochgeladen wird, oder der Hochladevorgang bereits abgeschlossen ist. </p>
<p>Wird die Datei gerade hochgeladen, enthält das von APC zurückgegebene Feld folgende Informationen:</p>
<table>
<thead>
<tr>
<th>Element</th>
<th>Inhalt</th>
<th>Typ</th>
</tr>
</thead>
<tbody>
<tr>
<td>total</td>
<td>Größe der Datei in Bytes</td>
<td>int</td>
</tr>
<tr>
<td>current</td>
<td>Bereits hochgeladene Bytes</td>
<td>int</td>
</tr>
<tr>
<td>filename</td>
<td>Name der Datei</td>
<td>string</td>
</tr>
<tr>
<td>name</td>
<td>Name des Formularelement (Datei-Element)</td>
<td>string</td>
</tr>
<tr>
<td>done</td>
<td>Hochladen abgeschlossen?</td>
<td>int (0/1)</td>
</tr>
<tr>
<td>start_time</td>
<td>Wann wurde der Hochladevorgang begonnen (Unix-Zeitstempel)</td>
<td>float</td>
</tr>
</tbody>
</table>
<p>Wenn der Hochladevorgang abgeschlossen wurde, kommen noch folgende Elemente hinzu:</p>
<table>
<thead>
<tr>
<th>Element</th>
<th>Inhalt</th>
<th>Typ</th>
</tr>
</thead>
<tbody>
<tr>
<td>rate</td>
<td>Wie viele Bytes pro Sekunde übertragen wurden</td>
<td>float</td>
</tr>
<tr>
<td>temp_filename</td>
<td>Der temporäre Dateiname</td>
<td>string</td>
</tr>
<tr>
<td>cancel_upload</td>
<td>0 Wenn die Datei erfolgreich hochgeladen wurde, sonst >0 (Fehlercode)</td>
<td>int</td>
</tr>
</tbody>
</table>
<h2>Mehrere Dateien hochladen?</h2>
<p>Es ist auch möglich den Hochladevorgang von mehreren Dateien zu überwachen, man kann aber erst nach dem Hochladen feststellen, wie groß jede einzelne Datei war/ist, da APC die Dateigrößen zusammenrechnet. Braucht man diese Information unbedingt, kann man mehrere Formulare mit je einer Datei, und unterschiedlichen APC_UPLOAD_PROGRESS-IDs erstellen.</p>
<h2>Wie erstelle ich denn jetzt einen Fortschrittsbalken?</h2>
<p>Wie man Fortschrittsbalken erstellt, habe ich in <a href="http://www.antusblog.de/2009/07/27/fortschrittsbalken-mit-cssjavascript/">diesem Artikel</a> beschrieben. Man könnte obiges Skript wie folgt modifizieren um einen Fortschrittsbalken zu implementieren (ich verwende in diesem Beispiel die dwProgressBar):<br />
<strong>status.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span>apc_fetch<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'upload_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p><strong>hochladen.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- [...] --&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;mootools-1.2.3-core-yc.js&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dwprogressbar.js&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
			function aktualisiere() {
				var anfrage = null;
&nbsp;
				if (window.XMLHttpRequest) {
					anfrage = new XMLHttpRequest();
				}
				else if (window.ActiveXObject) {
					anfrage = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
				}
&nbsp;
				anfrage.onreadystatechange = function() {
					if ((anfrage.readyState == 4) <span style="color: #ddbb00;">&amp;&amp; (anfrage.status == 200)) {</span>
<span style="color: #ddbb00;">						var ergebnis = eval('(' + anfrage.responseText + ')');</span>
						if (ergebnis.done == 1) {
							if (ergebnis.cancel_upload == 0) {
								document.getElementById('status').innerHTML = 'Hochgeladen!';
							}
							else {
								document.getElementById('status').innerHTML = 'Fehler/Abgebrochen.';
							}
						}
						else {
							//document.getElementById('status').innerHTML = Math.round((ergebnis.current * 100) / ergebnis.total) + '%';
							document.fsb.set(Math.round((ergebnis.current * 100) / ergebnis.total));
						}
					}
				}
&nbsp;
				anfrage.open('GET', 'status.php?id=' + document.forms.dateihochladen.APC_UPLOAD_PROGRESS.value);
				anfrage.send(null);
			}
&nbsp;
			function ladeHoch(elem) {
				elem.disabled = true;
&nbsp;
				document.fsb = new dwProgressBar({
					container: $('status'),
					startPercentage: 0,
					speed: 1000,
					boxID: 'rahmen',
					percentageID: 'balken',
					step: 10,
					allowMore:0,
					displayID: 'text',
					displayText: true
				});
&nbsp;
				setInterval('aktualisiere()', 1000);
			}
		<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>&gt;</span>
			#rahmen {
				background:url('gfx/normal.png') right center no-repeat; width:300px; height:30px;
				display:inline-block;
			}
			#balken {
				background:url('gfx/farbig.png') left center no-repeat; height:30px;
			}
			#text {
				font-size:16px;
				line-height:20px;
				vertical-align:top;
				padding-left:10px;
				display:inline-block;
			}
		<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span>
<span style="color: #808080; font-style: italic;">&lt;!-- [...] --&gt;</span></pre></div></div>

<p><em>Ich hoffe ich konnte euch einen kleinen Einblick in das Thema Fortschrittsanzeige beim Hochladen von Dateien geben. Anhand dieses Artikels (und der vorangehenden zum Thema APC/Dateien hochladen) sollte es möglich sein, ein individuelles Formular zum Hochladen von Dateien, mit Fortschrittsbalken, etc. zu erstellen. </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/08/12/fortschrittsanzeige-beim-hochladen-von-dateien/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Konfiguration von APC</title>
		<link>http://www.antusblog.de/2009/08/12/konfiguration-von-apc/</link>
		<comments>http://www.antusblog.de/2009/08/12/konfiguration-von-apc/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:14:13 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Alternative PHP Cache]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Konfiguration]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1669</guid>
		<description><![CDATA[Die Standardkonfiguration von APC ist für die meisten Systeme gut geeignet. Möchte man dennoch etwas an der Konfiguration ändern, muss man die im folgenden beschriebenen Optionen einfach in eine PHP-Konfigurationsdatei (beispielsweise php.ini oder apc.ini) eintragen. Die drei wichtigsten Einstellungen sind wohl die Größe des Zwischenspeichers, die Überwachung des Hochladevorgangs von Dateien, und ob APC bei [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Konfiguration.png"><img class="aligncenter size-full wp-image-1579" title="Konfiguration von APC" src="http://www.antusblog.de/wp-content/uploads/2009/06/APC.Konfiguration.png" alt="Konfiguration von APC" width="500" height="130" /></a>Die Standardkonfiguration von APC ist für die meisten Systeme gut geeignet. Möchte man dennoch etwas an der Konfiguration ändern, muss man die im folgenden beschriebenen Optionen einfach in eine PHP-Konfigurationsdatei (beispielsweise <code>php.ini</code> oder <code>apc.ini</code>) eintragen.</p>
<p>Die drei wichtigsten Einstellungen sind wohl die Größe des Zwischenspeichers, die Überwachung des Hochladevorgangs von Dateien, und ob APC bei jeder Anfrage überprüfen soll, ob eine Datei modifiziert wurde.</p>
<p><span id="more-1669"></span></p>
<h3>Die Größe des Zwischenspeichers</h3>
<p>Die Größe des Zwischenspeichers lässt sich über die Konfigurationsoptionen <code>apc.shm_size</code> und <code>apc.shm_segments</code> einstellen. Erstere legt fest wie groß ein gemeinsames Speichersegment (Shared Memory) sein darf, letztere legt fest aus wie vielen solchen Segmenten der Zwischenspeicher besteht. Bei manchen Betriebssystemen können solche Speichersegmente nur wenige Megabytes groß sein, weswegen entweder mehrere Segmente verwendet werden müssen, oder die Betriebssystemkonfiguration angepasst werden muss. Linux hat standardmäßig eine maximale Segmentgröße von 32 MiB, BSD von 4 MiB.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; 2 Segmente von je 30 MiB = 60 MiB
apc.shm_size = 30
apc.shm_segments = 2</pre></div></div>

<h3>Hochladen von Dateien</h3>
<p>Ist <code>apc.rfc1867</code> eingeschaltet (<code>On</code>), legt APC beim Hochladen von Dateien einen Eintrag im Zwischenspeicher ab, der Informationen über den Hochladevorgang enthält. Mit diesen Daten lässt sich beispielsweise eine Fortschrittsanzeige realisieren. Damit APC einen solchen Eintrag erstellt, muss das Formular allerdings ein Feld mit einem bestimmten Namen, standardmäßig <code>APC_UPLOAD_PROGRESS</code>, haben. APC erstellt dann einen Eintrag im Zwischenspeicher mit dem Namen <code>upload_&lt;Schlüssel&gt;</code> wobei der Schlüssel dem Wert der <code>value</code>-Eigenschaft des Formularfeldes entspricht.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; Es sollen Informationen über den Hochladevorgang gespeichert werden.
apc.rfc1867 = On
; Benutze upload_ als Präfix für den Eintrag im Zwischenspeicher.
apc.rfc1867_prefix = upload_
; Name des versteckten Formularelementes, welches diese Funktionalität aktiviert.
apc.rfc1867_name APC_UPLOAD_PROGRESS
; Wie oft sollen die Informationen aktualisiert werden?
; 0 = So oft wie möglich. (Kann den Hochladevorgang verlangsamen)
; % = % der Dateigröße (z.B. 2% = alle 2% wird aktualisiert)
; &lt;Zahl&gt;&lt; ,k,m,g&gt; Nach  Bytes, Kilobytes, Megabytes oder Gigabytes.
apc.rfc1867 = 50k</pre></div></div>

<p>Mehr Informationen zu dieser Funktion finden sich im Artikel <a href="http://www.antusblog.de/?p=1849">Fortschrittsanzeige beim Hochladen von Dateien</a>. </p>
<h3>Wurde die Datei modifiziert?</h3>
<p>Die Option <code>apc.stat</code> gibt an, ob bei jedem Aufruf überprüft werden soll, ob die Datei im Zwischenspeicher auch der Datei auf der Festplatte entspricht. Ist diese Option abgeschaltet (<code>Off</code>), wird keine Überprüfung durchgeführt, was zwar die Geschwindigkeit merklich verbessert, es aber auch nötig macht den Zwischenspeicher neu aufzubauen, damit die Änderungen am Quelltext einer Datei wirksam werden.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">apc.stat = On</pre></div></div>

<p>Auch wenn diese Option abgeschaltet ist, werden mit relativem Pfad <a href="http://www.antusblog.de/2009/05/30/dateien-einbinden-inkludieren-2/">inkludierte Dateien</a> beim Inkludieren vorher überprüft. Bei absoluten Pfaden (also solchen die mit einem / beginnen), ist das nicht der Fall.</p>
<h4>Viele gleichzeitige Zugriffe</h4>
<p>Beim Starten von stark ausgelasteten Servern bzw. wenn viele Dateien modifiziert wurden, kann es passieren, dass mehrere Prozesse versuchen die gleiche Datei für den Zwischenspeicher zu kompilieren. Mittels <code>apc.write_lock</code> wird festgelegt, dass in diesem Fall nur ein Prozess die Datei zwischenspeichert, während die anderen Prozesse die noch nicht-zwischengespeicherte Datei einfach nur ausliefern. Ist die Option abgeschaltet, müssten die anderen Prozesse auf den ersten warten.</p>
<h4>Überschreiben von Dateien</h4>
<p>Wenn man eine Datei überschreibt, kann es passieren, das genau in dem Moment ein Zugriff auf diese Datei erfolgt. In dem Fall würde der Benutzer wahrscheinlich eine fehlerhafte Seite sehen (zum Teil die neue Datei, zum Teil noch die alte). Die Option <code>apc.file_update_protection</code> schützt davor, das eine erst zum Teil auf die Festplatte geschriebene Datei zwischengespeichert wird. Der Benutzer der in dem ungünstigen Moment auf die Datei zugreift bekommt zwar trotzdem eine fehlerhafte Seite ausgeliefert, aber die fehlerhafte Seite landet nicht im Zwischenspeicher.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; Um in den Zwischenspeicher zu kommen muss eine Datei min. 2 Sekunden alt sein.
apc.file_update_protection = 2</pre></div></div>

<p>Auf Systemen mit hoher Festplattenauslastung ist es sinnvoll diesen Wert noch etwas zu erhöhen. Wenn man sich sicher ist, das Dateien immer <a href="http://de.wikipedia.org/wiki/Atomar#Informatik">atomar</a> überschrieben werden, kann dieser Wert auf 0 gesenkt werden. (Beispielsweise wenn man die neue Datei erst in eine temporäre Datei schreibt und sie dann umbenennt.)</p>
<h3>Lebenszeit von Dateien</h3>
<p>Da die Größe des Zwischenspeichers begrenzt ist, könnte es unter Umständen passieren, dass dieser voll wird und kein Platz mehr für neue Dateien/Variablen ist. APC bietet allerdings die Möglichkeit Dateien oder Variablen auf die eine bestimmte Zeit lang nicht mehr zugegriffen wurde, aus dem Zwischenspeicher zu nehmen, um wieder Platz zu schaffen. Diese Funktion wird durch die Optionen <code>apc.ttl</code> (für Dateien) und <code>apc.user_ttl</code> (für Variablen) beeinflusst, welche festlegen, wie lange eine Datei/Variable nicht mehr aufgerufen werden darf bevor sie entfernt wird. Ist dieser Wert 0, ist die Funktion abgeschaltet. In diesem Fall wird der Zwischenspeicher komplett geleert, wenn er voll ist.</p>
<p>Außerdem gibt es noch <code>apc.gc_ttl</code>, wodurch bestimmt wird, wie oft APC den Zwischenspeicher auf veraltete Dateien überprüft, bzw. diese löscht.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">apc.ttl = 0
apc_user_ttl = 0
apc.gc_ttl = 3600</pre></div></div>

<h3>Filtern von Dateien</h3>
<p>Standardmäßig speichert APC alle aufgerufenen PHP-Dateien im Zwischenspeicher. Mithilfe von Filtern kann man aber einstellen, das nur bestimmte Dateien zwischengespeichert werden, bzw. bestimmte Dateien nicht in den Zwischenspeicher kommen. Dazu wird die Option <code>apc.filters</code> verwendet, diese erwartet eine durch Komma getrennte Liste von regulären Ausdrücken. Ein + oder ein &#8211; vor jedem Ausdruck legt fest ob auf den Ausdruck passende Dateien zwischengespeichert werden (+) oder nicht gespeichert werden (-). Wird das Plus/Minus weggelassen, wird Minus angenommen.</p>
<p>Die Option <code>apc.cache_by_default</code> gibt an ob APC standardmäßig alle PHP-Dateien zwischenspeichert, oder keine. Mit <code>apc.max_file_size</code> können außerdem Dateien ab einer bestimmten Größe vom Zwischenspeicher ausgeschlossen werden.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; Alle Dateien zwischenspeichern
apc.cache_by_default = 1
; Ausser: Dateien in /nicht_zwischenspeichern/ und
; die Datei mit dem Namen blablabla.php
apc.filters = &quot;/nicht_zwischenspeichern/.*,blablabla\.php&quot;
; Keine Datei groesser als 1 MB
apc.max_file_size = 1M</pre></div></div>

<p>Hinweis: Beim Inkludieren von Dateien wird dieser Filter auf den Dateinamen der in der include-Anweisung steht angewendet, nicht auf den absoluten Pfad der Datei.</p>
<h3>Tabelle: Alle Optionen</h3>
<p>In dieser Übersicht stehen noch mal alle Optionen, mit den Standardwerten und einer sehr kurzen Beschreibung. Eine ausführlichere Beschreibung der Optionen findet sich im <a href="http://de.php.net/manual/de/apc.configuration.php">PHP-Handbuch</a>. Wenn bei Zeitangaben keine Einheit dabei steht, sind Sekunden gemeint.</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Standardwert</th>
<th>Beschreibung</th>
</tr>
</thead>
<tbody>
<tr>
<td>apc.enabled</td>
<td>1</td>
<td>APC aktivieren (1) bzw. deaktivieren (0).</td>
</tr>
<tr>
<td>apc.enable_cli</td>
<td>0</td>
<td>Schaltet APC auch für die Kommandozeile an. (Eigentlich nur für Testzwecke sinnvoll.)</td>
</tr>
<tr>
<td>apc.shm_size</td>
<td>30</td>
<td>Größe eines Speichersegmentes in MiB.</td>
</tr>
<tr>
<td>apc.shm_segments</td>
<td>1</td>
<td>Anzahl von Speichersegmenten für den Zwischenspeicher (Segmente * Segmentgröße = Größe des Zwischenspeichers)</td>
</tr>
<tr>
<td>apc.num_files_hint</td>
<td>1000</td>
<td>Hinweis für APC, wie viele Dateien ungefähr im Zwischenspeicher gelagert werden. Wenn man sich nicht sicher ist, kann man hier auch 0 eintragen.</td>
</tr>
<tr>
<td>apc.user_entries_hint</td>
<td>4096</td>
<td>Hinweis, wie viele Variablen im Zwischenspeicher gespeichert werden. Auch hier kann 0 eingetragen werden, wenn man sich nicht sicher ist.</td>
</tr>
<tr>
<td>apc.ttl</td>
<td>0</td>
<td>Wie lange eine Datei nicht mehr aufgerufen werden darf bevor sie aus dem Zwischenspeicher entfernt wird. (0 = Funktion deaktiviert)</td>
</tr>
<tr>
<td>apc.user_ttl</td>
<td>0</td>
<td>Wie &lt;apc.ttl&gt;, nur für Variablen.</td>
</tr>
<tr>
<td>apc.gc_ttl</td>
<td>3600</td>
<td>Gibt an, in welchen Zeitabständen veraltete Dateien aus dem Zwischenspeicher entfernt werden.</td>
</tr>
<tr>
<td>apc.cache_by_default</td>
<td>1</td>
<td>Standardmäßig alle/keine Datei zwischenspeichern.</td>
</tr>
<tr>
<td>apc.filters</td>
<td>&#8220;&#8221;</td>
<td>Filter (welche Datei zwischengespeichert wird/welche nicht.)</td>
</tr>
<tr>
<td>apc.max_file_size</td>
<td>1M</td>
<td>Max. Dateigröße. Größere Dateien kommen nicht in den Zwischenspeicher.</td>
</tr>
<tr>
<td>apc.stat</td>
<td>1</td>
<td>Bei jedem Aufruf überprüfen ob die Datei im Zwischenspeicher auch der auf der Festplatte entspricht.</td>
</tr>
<tr>
<td>apc.write_lock</td>
<td>1</td>
<td>Bei mehreren gleichzeitigen Zugriffen auf eine nicht-zwischengespeicherte Datei: Ein Prozess kompiliert, die anderen liefern die Datei so aus anstatt darauf zu warten, das der erste Prozess fertig wird.</td>
</tr>
<tr>
<td>apc.stat_ctime</td>
<td>0</td>
<td>Normalerweise wird nur überprüft, wann die Datei zuletzt verändert wurde, ist diese Option eingeschaltet wird auch überprüft wann die Datei erstellt wurde. (Behebt einige Probleme mit svn/rsync.)</td>
</tr>
<tr>
<td>apc.file_update_protection</td>
<td>2</td>
<td>Dateien erst ab einem Alter von X Sekunden zwischenspeichern.</td>
</tr>
<tr>
<td>apc.rfc1867</td>
<td>0</td>
<td>Hochladevorgang von Dateien überwachen.</td>
</tr>
<tr>
<td>apc.rfc1867_prefix</td>
<td>upload_</td>
<td>Präfix für den Eintrag im Zwischenspeicher.</td>
</tr>
<tr>
<td>apc.rfc1867_name</td>
<td>APC_UPLOAD_PROGRESS</td>
<td>Name des versteckten Formularelements.</td>
</tr>
<tr>
<td>apc.rfc1867_freq</td>
<td>0</td>
<td>Frequenz der Aktualisierungen.</td>
</tr>
<tr>
<td>apc.include_once_override</td>
<td>0</td>
<td>include_once- und require_once-Anweisungen optimieren.</td>
</tr>
<tr>
<td>apc.report_autofilter</td>
<td>0</td>
<td>Aufgrund von Problemen mit früher/später Bindung nicht-zwischengespeicherte Dateien protokollieren.</td>
</tr>
<tr>
<td>apc.mmap_file_mask</td>
<td>NULL</td>
<td>Die Dateimaske für <code>mktemp</code>, anhand der entschieden wird, ob das Speicherabbild Shared Memory- oder dateisystemgestützt ist.</td>
</tr>
<tr>
<td>apc.localcache</td>
<td>0</td>
<td>Aktiviert einen Sperr-freien &#8220;shadow-cache&#8221; (Prozess-lokal). Dadurch wird das Warten auf die <a href="http://de.wikipedia.org/wiki/Lock">Sperre</a> beim Schreiben in den Zwischenspeicher vermindert.</td>
</tr>
<tr>
<td>apc.localcache.size</td>
<td>512</td>
<td>Größe des &#8220;shadow-cache&#8221;, es wird empfohlen hier die Hälfte von <em>apc.num_files_hint</em> zu verwenden.</td>
</tr>
<tr>
<td>apc.coredump_unmap</td>
<td>0</td>
<td>APC versucht bei einem fatalen Fehler zu verhindern, das der Zwischenspeicher mit im <a href="http://de.wikipedia.org/wiki/Dump">Speicherauszug</a> (der für Zwecke der Fehlerdiagnose erstellt wird) landet. Bei einem großen Zwischenspeicher kann ein fataler Fehler sonst die Systemstabilität beeinträchtigen. Diese Funktion ist allerdings auch nicht ganz ungefährlich, da sie im Falle eines fatalen Fehlers zu undefiniertem Verhalten führen kann.</td>
</tr>
</tbody>
</table>
<p>Einige Optionen sind veraltet, und sollten nicht mehr verwendet werden.</p>
<ul>
<li>apc.optimization</li>
<li>apc.slam_defense <em>(anstatt dessen sollte apc.write_lock verwendet werden.)</em></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/08/12/konfiguration-von-apc/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Installation von APC</title>
		<link>http://www.antusblog.de/2009/08/12/installation-von-apc/</link>
		<comments>http://www.antusblog.de/2009/08/12/installation-von-apc/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 20:45:59 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Alternative PHP Cache]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[Zwischenspeicher]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1508</guid>
		<description><![CDATA[APC ist eine PECL-Erweiterung, die nicht zum Installationsumfang von PHP 5 gehört. Ab PHP 6 soll APC standardmäßig in PHP enthalten sein. Ob APC bereits installiert ist, kann man in der Ausgabe von phpinfo() sehen. Es gibt zwei Möglichkeiten APC zu installieren: Entweder man installiert es über die Paketverwaltung der verwendeten Linux-Distribution, was die Vorteile [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/APC.in.der.phpinfo.png"><img class="aligncenter size-full wp-image-1573" title="In der Ausgabe von phpinfo() findet sich auch ein Abschnitt über APC" src="http://www.antusblog.de/wp-content/uploads/2009/06/APC.in.der.phpinfo.png" alt="In der Ausgabe von phpinfo() findet sich auch ein Abschnitt über APC" width="430" height="200" /></a></p>
<p>APC ist eine PECL-Erweiterung, die nicht zum Installationsumfang von PHP 5 gehört. Ab PHP 6 soll APC standardmäßig in PHP enthalten sein. Ob APC bereits installiert ist, kann man in der Ausgabe von <code>phpinfo()</code> sehen. </p>
<p><span id="more-1508"></span></p>
<p>Es gibt zwei Möglichkeiten APC zu installieren: Entweder man installiert es über die Paketverwaltung der verwendeten Linux-Distribution, was die Vorteile hat, das man sich über die Abhängigkeiten keine Gedanken machen muss, und das es von der Paketverwaltung (meistens) schon automatisch aktiviert wird. Die andere Möglichkeit ist die Installation mittels PECL.</p>
<h2>Installation über die Paketverwaltung</h2>
<p>Viele Distributionen bieten bereits Pakete für APC an, ist das bei der verwendeten Distribution nicht der Fall, muss es über PECL installiert werden. Bei Debian heißt das Paket <code>php-apc</code>, bei Gentoo <code>pecl-apc</code>, bei anderen Distributionen wahrscheinlich ähnlich. Hier hilft einem die Suchfunktion der entsprechenden Paketverwaltung.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Debian</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php-apc
<span style="color: #666666; font-style: italic;"># Gentoo</span>
emerge pecl-apc</pre></div></div>

<p>Die meisten Paketverwalter aktivieren APC automatisch (tragen die Erweiterung in eine PHP-Konfigurationsdatei ein), es sollte also nur noch ein Neustart des Webservers nötig sein (siehe weiter unten).</p>
<h2>Installation mit PECL</h2>
<p>Wenn alle für die Installation benötigten Programme/Abhängigkeiten installiert sind, kann APC mittels folgendem Befehl installiert werden:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pecl <span style="color: #c20cb9; font-weight: bold;">install</span> apc</pre></div></div>

<p>Zur Installation werden die Entwicklerpakete von PHP und dem Webserver (Apache) vorausgesetzt, außerdem werden ein Compiler (<code>gcc</code>), sowie div. andere Entwicklerpakete wie beispielsweise make benötigt. Wenn etwas fehlt, wird PECL einen bei der Installation darauf hinweisen, das entsprechende Programm/Paket kann man dann einfach über die Paketverwaltung installieren.</p>
<p>Mehr Informationen über die Installation von PHP-Erweiterungen mittels PECL finden sich in der <a href="http://de3.php.net/manual/de/install.pecl.php">PHP-Dokumentation</a>.</p>
<p>Nach der erfolgreichen Installation muss APC noch in einer Konfigurationsdatei von PHP (es kann mehrere geben) eingetragen und der Webserver neugestartet werden.</p>
<h2>APC-Modul laden</h2>
<p>Nachdem APC installiert wurde, muss noch dafür gesorgt werden, das PHP das Modul auch lädt. Dazu muss in einer Konfigurationsdatei, die PHP beim Start auswertet (z.B. der <code>php.ini</code>) ein Eintrag gemacht werden. Wenn APC über die Paketverwaltung installiert wurde, ist solch ein Eintrag wahrscheinlich sogar schon vorhanden. Dies kann man überprüfen indem man den Webserver neustartet und sich die Ausgabe von <code>phpinfo()</code> ansieht. Ansonsten muss man ihn selbst hinzufügen.</p>
<h3>Wo befindet sich die PHP-Konfigurationsdatei?</h3>
<p>Um herauszufinden, wo sich die Konfigurationsdatei von PHP befindet, legt man einfach eine PHP-Datei mit folgendem Inhalt an:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">phpinfo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Wenn man diese Datei nun im Browser aufruft, erhält man eine Übersicht der PHP-Konfiguration. Am Anfang unter dem Eintrag <strong>Loaded Configuration File </strong>steht, wo sich die Konfigurationsdatei von PHP befindet. Unter <strong>additional .ini files parsed</strong> finden sich weitere Konfigurationsdateien die von PHP ausgewertet werden, ist hier schon eine <code>apc.ini</code> dabei, hat die Paketverwaltung APC wohl schon aktiviert.</p>
<p>Wichtig: Auf einem produktiven System sollte man die Datei in der <a href="http://de2.php.net/manual/de/function.phpinfo.php"><code>phpinfo()</code></a> aufgerufen wird wieder löschen oder zumindest für normale Benutzer unzugänglich machen, nachdem man die benötigten Informationen hat.  Sonst könnte jeder der den Namen der Datei kennt, herausfinden wie der Server konfiguriert ist.</p>
<h3>Eintrag in der Konfigurationsdatei</h3>
<p>Ist noch kein Eintrag für APC vorhanden, muss er hinzugefügt werden. Dazu schreibt man folgendes in die Konfigurationsdatei:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">extension=apc.so</pre></div></div>

<p>Nach einem Neustart des Webservers sollte APC dann automatisch geladen werden. Das kann ebenfalls in der Ausgabe von <code>phpinfo()</code> überprüft werden, dort müsste irgendwo ein Eintrag mit der Überschrift <em>apc</em> angezeigt werden.</p>
<h2>Webserver neustarten</h3>
<p>Damit eine geänderte PHP-Konfiguration wirksam wird, muss der Webserver angewiesen werden, diese neu einzulesen. Dazu ist ein Neustart des Webservers erforderlich. Beim Apache kann einer der folgenden beiden Befehle dazu verwendet werden.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">apache2ctl graceful
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 graceful</pre></div></div>

<h2>Nach der Installation</h2>
<p>Die Standardkonfiguration ist für die meisten Anwender gut geeignet, einige Optionen wie beispielsweise die Größe des Zwischenspeichers kann man aber noch anpassen. Welche Konfigurationsmöglichkeiten es gibt, wird im Artikel <a href="http://www.antusblog.de/?p=1669">Konfiguration von APC</a> beschreiben.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/08/12/installation-von-apc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dateien hochladen in PHP</title>
		<link>http://www.antusblog.de/2009/06/10/dateien-hochladen-php/</link>
		<comments>http://www.antusblog.de/2009/06/10/dateien-hochladen-php/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 19:17:27 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Datei]]></category>
		<category><![CDATA[Dateiendung]]></category>
		<category><![CDATA[Formular]]></category>
		<category><![CDATA[hochladen]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[move_uploaded_file]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1462</guid>
		<description><![CDATA[Es gibt viele Projekte bei denen man dem Benutzer die Möglichkeit geben möchte selbst Dateien auf den Server hochzuladen, beispielsweise bei Bilderhostern, oder Foren, bei denen der Benutzer die Möglichkeit hat Dateien an einen Beitrag anzuhängen. Sowas lässt sich mit PHP problemlos realisieren. In diesem Artikel beschreibe ich, wie man ein Formular zum Hochladen von [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/dateienhochladenformular.png"><img class="aligncenter size-full wp-image-1464" title="Ein Formular zum Auswählen einer Datei" src="http://www.antusblog.de/wp-content/uploads/2009/06/dateienhochladenformular.png" alt="Ein Formular zum Auswählen einer Datei" width="500" height="150" /></a></p>
<p>Es gibt viele Projekte bei denen man dem Benutzer die Möglichkeit geben möchte selbst Dateien auf den Server hochzuladen, beispielsweise bei Bilderhostern, oder Foren, bei denen der Benutzer die Möglichkeit hat Dateien an einen Beitrag anzuhängen. Sowas lässt sich mit PHP problemlos realisieren.</p>
<p>In diesem Artikel beschreibe ich, wie man ein Formular zum <strong>Hochladen von Dateien</strong> erstellt und wie man die Dateien serverseitig mit PHP behandelt. Außerdem erkläre ich wie <strong>mehrere Dateien auf einmal</strong> hochgeladen werden können.</p>
<p><span id="more-1462"></span></p>
<h2>Das Dateiformular</h2>
<p>Zuerst einmal wird ein Formular benötigt, in dem der Benutzer eine Datei auswählen kann. Ein <code>input</code>-Element vom Typ <code>file</code> erstellt ein Eingabefeld und eine Durchsuchen-Schaltfläche, mittels derer der Benutzer eine Datei auswählen kann. Das versteckte <code>input</code>-Element mit dem Namen <code>MAX_FILE_SIZE</code> ist ein Hinweis für den Browser des Benutzers, <code>value</code> gibt in Bytes an, wie groß eine hochgeladene Datei maximal sein darf. Die Größe der Datei muss natürlich serverseitig noch einmal überprüft werden, da manche Browser die Angabe evtl. nicht beachten, und weil sie leicht umgangen werden kann. PHP überprüft zwar selbst, ob die Datei größer als MAX_FILE_SIZE ist, aber da diese Angabe leicht manipuliert werden kann, bietet diese Überprüfung keine Sicherheit.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;uploaded.php&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">fieldset</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">legend</span>&gt;</span>Datei hochladen<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">legend</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span>&gt;</span>Bitte eine Datei ausw<span style="color: #ddbb00;">&amp;auml;</span>hlen.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
		<span style="color: #808080; font-style: italic;">&lt;!-- Hinweis fuer den Browser des Benutzers, maximale Dateigroesse --&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;MAX_FILE_SIZE&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;100000&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
		<span style="color: #808080; font-style: italic;">&lt;!-- Eingabefeld+Durchsuchen-Schaltflaeche --&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;beispieldatei&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
		<span style="color: #808080; font-style: italic;">&lt;!-- Schaltflaeche zum Absenden der Datei --&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Hochladen&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">fieldset</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></pre></div></div>

<p>Die <code>action</code>-Eigenschaft des form-Elements gibt an, an welche Adresse/Datei die Daten übertragen werden sollen. Mit <code>method</code> wird angegeben, wie die Daten übertragen werden sollen, beim POST-Verfahren sendet der Browser eine spezielle POST-Anfrage mit den Daten an den Server. Die Eigenschaft <code><a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4">enctype</a></code> gibt die Kodierung der übertragenen Daten an, hier muss man <code>multipart/form-data</code> verwenden.</p>
<h2>Die hochgeladene Datei verarbeiten</h2>
<p>Wenn der Benutzer das Formular absendet wird die unter <code>action</code> angegebene Seite aufgerufen, dabei wird die Datei vom Browser an den Server gesendet. Die Datei wird vom Server in einem temporären Verzeichnis gespeichert. Im PHP-Skript muss diese nun verarbeitet und an ihren Bestimmungsort verschoben werden.<br />
PHP sammelt die wichtigsten Informationen über die Datei im autoglobalen Feld <code>$_FILES</code>. Für jede hochgeladene Datei wird ein Element mit dem gleichen Namen wie das input-Element des Formulars (im Beispiel: beispieldatei) in diesem Feld angelegt. Auch dieses Element ist wieder ein Feld, mit folgenden Elementen:</p>
<table>
<thead>
<tr>
<th>Element</th>
<th>Inhalt</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>Der Name der Datei auf dem Rechner des Benutzers</td>
</tr>
<tr>
<td>type</td>
<td>MIME-Typ der Datei, z.B. &#8220;image/png&#8221;</td>
</tr>
<tr>
<td>tmp_name</td>
<td>Der Pfad und Name, unter der die Datei gespeichert wurde (im temporären Verzeichnis), beispielsweise &#8220;/tmp/phpKnTtNy&#8221;.</td>
</tr>
<tr>
<td>error</td>
<td>Der Fehlercode, mittels diesem kann überprüft werden ob beim Hochladen ein Fehler aufgetreten ist.</td>
</tr>
<tr>
<td>size</td>
<td>Die Größe der Datei, in Bytes.</td>
</tr>
</tbody>
</table>
<p><strong></strong><div id="attachment_1522" class="wp-caption alignright" style="width: 230px"><a href="http://www.antusblog.de/wp-content/uploads/2009/06/FILES.Feld.Inhalt.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/06/FILES.Feld.Inhalt.png" alt="Beispiel: So könnte der Inhalt von $_FILES nach dem erfolgreichen hochladen einer Datei aussehen." title="Beispiel: So könnte der Inhalt von $_FILES nach dem erfolgreichen hochladen einer Datei aussehen." width="220" height="233" class="size-full wp-image-1522" /></a><p class="wp-caption-text">Beispiel: So könnte der Inhalt von $_FILES nach dem erfolgreichen hochladen einer Datei aussehen.</p></div>Anhand dieser Daten kann die Datei erstmal validiert werden, so können Dateien die zu groß oder zu klein sind, den falschen Dateityp/Endung haben, aussortiert werden. Dateien mit der Endung .php sollten auf jeden Fall aussortiert bzw. wenigstens umbenannt werden, sonst können nämlich PHP-Dateien hochgeladen werden die auch vom PHP-Interpreter ausgeführt werden würden! </p>
<h3>Verschieben der Datei</h3>
<p>Um die Datei nun weiter zu bearbeiten bzw. sie zu speichern, muss sie vom temporären Verzeichnis in das gewünschte Zielverzeichnis verschoben werden. Nach der Ausführung des Skripts wird die Datei gelöscht, falls sie sich noch im temporären Verzeichnis befindet. Um eine Datei nicht zu speichern, genügt es also, sie einfach nicht aus dem temporären Verzeichnis rauszuholen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$zielverzeichnis</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'./hochgeladen/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'beispieldatei'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> UPLOAD_ERR_OK<span style="color: #009900;">&#41;</span>
	<span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Ein Fehler ist aufgetreten.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'beispieldatei'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
                       <span style="color: #000088;">$zielverzeichnis</span> <span style="color: #339933;">.</span> <span style="color: #990000;">basename</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'beispieldatei'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Datei wurde hochgeladen!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ein Fehler ist aufgetreten!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Zuerst wird die error-Variable überprüft, wenn ein Fehler aufgetreten ist, bricht das Skript ab. Anschließend wird die Datei mittels <a href="http://de2.php.net/manual/de/function.move-uploaded-file.php"><code>move_uploaded_file($datei, $ziel)</code></a> in das Zielverzeichnis verschoben. Die Funktion überprüft ob es sich bei der übergebenen Datei um eine hochgeladene Datei handelt, ist das nicht der Fall, wird sie nicht verschoben und es wird <code>false</code> zurückgegeben. Konnte die Datei aus irgendeinem Grund nicht verschoben werden, wird ebenfalls <code>false</code> zurückgegeben, sowie eine Warnung ausgegeben. Die Zieldatei wird überschrieben, wenn sie bereits existiert.</p>
<h4>Wozu der basename-Aufruf?</h4>
<p>Das Beispielskript speichert die Datei unter dem selben Namen, den sie auch auf dem Rechner des Benutzers hat. Die <a href="http://de2.php.net/manual/de/function.basename.php"><code>basename($pfad)</code></a>-Funktion extrahiert den Dateinamen einer Datei aus einer Pfadangabe.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #990000;">basename</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/etc/passwd&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Ausgabe: passwd</span></pre></div></div>

<p>Durch den <code>basename</code>-Aufruf wird sichergestellt, das es sich bei dem Dateinamen wirklich um einen Dateinamen und nicht um einen Pfad handelt. Ohne diese Überprüfung könnten böswillige Benutzer möglicherweise dafür sorgen das ihre Dateien in anderen Verzeichnissen als im Zielverzeichnis landen (Sicherheitslücke!).</p>
<h3>Die Datei validieren</h3>
<p>Um zu verhindern, das Benutzer Dateien hochladen, die dem Server oder anderen Benutzern schaden könnten , oder aus anderen Gründen unerwünscht sind, empfiehlt es sich eine hochgeladene Datei erst zu überprüfen, bevor sie verschoben wird.</p>
<ul>
<li>Die <strong>Dateigröße</strong>. Je nachdem wie die hochgeladenen Dateien verwendet werden, sollte man überprüfen, das der Benutzer keine unsinnig großen (oder kleinen) Dateien hochlädt. Der Speicherplatz auf dem Server ist schließlich begrenzt. Die Variable <code>$_FILES[...]['size']</code> kann hierzu verwendet werden.</li>
<li>Die <strong>Dateiendung</strong> bzw. der <strong>MIME-Typ</strong>. Oft sind nur bestimmte Arten von Dateien erwünscht, beispielsweise Bilder bei einem Bilderhoster. Unpassende Dateitypen können aussortiert werden. Dateien mit der Endung <code>.php</code> bzw. <code>.php3</code>/<code>.php4</code>/<code>.php5</code>/usw. sollten ebenfalls aussortiert werden, bzw. die Dateiendung sollte geändert werden (beispielsweise zu .phps), ansonsten können die Benutzer ausführbare PHP-Dateien hochladen, was in den meisten Fällen unerwünscht sein dürfte (Sicherheitslücke). Hierzu können die Variablen <code>$_FILES[...]['type']</code> (MIME-Typ) und <code>$_FILES[...]['name']</code> (Dateiname) verwendet werden. Mit folgender Funktion lässt sich die Dateiendung aus dem Dateinamen ermitteln:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> endungErmitteln<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dateiname</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">!==</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$punkt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strrpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dateiname</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dateiname</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #000088;">$punkt</span><span style="color: #009900;">&#41;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dateiname</span><span style="color: #339933;">,</span> <span style="color: #000088;">$punkt</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// Keine Dateiendung</span>
	<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Es ist noch zu beachten, das es Dateien ohne Endung gibt, und das Dateiendungen in allen möglichen Formen von Groß- und Kleinschreibung vorkommen können (Bsp. Bild.JpEg).</li>
<li>Der <strong>Dateiname</strong>. Der Name der Datei kann auf nicht erwünschte Zeichen überprüft werden, außerdem könnte man überprüfen ob der Dateiname nicht zu lang ist.</li>
<li><strong>Viren</strong> und andere <strong>Schädlinge</strong>. Ein Benutzer könnte (un-)absichtlich eine Datei hochladen die einen Virus bzw. einen Wurm o.Ä. enthält. Es gibt Erweiterungen für PHP, die es einem ermöglichen eine Datei auf solche Schadprogramme zu überprüfen.
<p style="padding-left:30px;"><a href="http://www.howtoforge.de/howto/wie-man-hoch-geladene-dateien-automatisch-auf-viren-uberpruft-mit-php-clamavlib">Wie man hochgeladene Dateien automatisch auf Viren überprüft mit php-clamavlib</a></p>
</li>
</ul>
<h3>Mögliche Fehler</h3>
<p>Beim Hochladen von Dateien können auch Fehler auftreten, deshalb enthält das <code>$_FILES</code>-Feld im Dateielement auch ein Element namens <code>error</code>, welches angibt ob ein Fehler aufgetreten ist, bzw. um welchen Fehler es sich handelt.</p>
<h4>Mögliche Fehlercodes in $_FILES[...]['error']</h4>
<p>Mit folgenden Fehlercodes kann der <code>error</code>-Wert verglichen werden, um herauszufinden, was für ein Fehler aufgetreten ist.</p>
<table>
<thead>
<tr>
<th>Zahl</th>
<th>Fehlercode</th>
<th>Bedeutung</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>UPLOAD_ERR_OK</td>
<td>Kein Fehler, die Datei wurde erfolgreich hochgeladen.</td>
</tr>
<tr>
<td>1</td>
<td>UPLOAD_ERR_INI_SIZE</td>
<td>Die Datei ist größer als <a href="http://de2.php.net/manual/en/ini.core.php#ini.upload-max-filesize">upload_max_filesize</a>, einer Option in der Konfigurationsdatei von PHP.</td>
</tr>
<tr>
<td>2</td>
<td>UPLOAD_ERR_FORM_SIZE</td>
<td>Die Datei ist größer, als im Formular mittels MAX_FILE_SIZE angegeben.</td>
</tr>
<tr>
<td>3</td>
<td>UPLOAD_ERR_PARTIAL</td>
<td>Die Datei wurde nur teilweise hochgeladen.</td>
</tr>
<tr>
<td>4</td>
<td>UPLOAD_ERR_NO_FILE</td>
<td>Es wurde keine Datei hochgeladen.</td>
</tr>
<tr>
<td>6</td>
<td>UPLOAD_ERR_NO_TMP_DIR</td>
<td>Es gibt kein temporäres Verzeichnis, unter dem die Datei abgelegt werden könnte. <em>Erst ab PHP 5.0.3</em></td>
</tr>
<tr>
<td>7</td>
<td>UPLOAD_ERR_CANT_WRITE</td>
<td>Die Datei konnte nicht erstellt werden, bzw. konnte nicht auf das Speichermedium (Festplatte) geschrieben werden. <em>Erst ab PHP 5.1.0</em></td>
</tr>
<tr>
<td>8</td>
<td>UPLOAD_ERR_EXTENSION</td>
<td>Der Hochladevorgang wurde durch eine PHP-Erweiterung gestoppt. <em>Erst ab PHP 5.2.0</em></td>
</tr>
</tbody>
</table>
<p>Die Überprüfung auf Fehler könnte beispielsweise so aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$fehlercode</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'beispieldatei'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fehlercode</span> <span style="color: #339933;">!=</span> UPLOAD_ERR_OK<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Beim Hochladen ist ein Fehler aufgetreten!&lt;/h2&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fehlercode</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> UPLOAD_ERR_INI_SIZE<span style="color: #339933;">:</span>
		<span style="color: #b1b100;">case</span> UPLOAD_ERR_FORM_SIZE<span style="color: #339933;">:</span> 
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Die Datei ist zu gro&amp;szlig;.'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> UPLOAD_ERR_PARTIAL<span style="color: #339933;">:</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Die Datei wurde nur teilweise hochgeladen.'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> UPLOAD_ERR_NO_FILE<span style="color: #339933;">:</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Es wurde keine Datei hochgeladen.'</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">default</span><span style="color: #339933;">:</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ein interner Fehler ist aufgetreten.'</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Eine E-Mail wurde an den Administrator geschickt.'</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Bitte versuchen Sie es zu einem späteren Zeitpunkt nochmal.'</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// E-Mail mit dem Fehlercode an den Admin schicken [...] ;-)</span>
			<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4>Optionen in der php.ini</h4>
<p>Die Option <code><a href="http://de2.php.net/manual/en/ini.core.php#ini.upload-max-filesize">upload_max_filesize</a></code> gibt an, wie groß die Dateien die hochgeladen werden, zusammen maximal sein dürfen. Es wird also beim Hochladen mehrerer Dateien nicht überprüft wie groß die einzelnen Dateien sind, sondern wie groß sie alle zusammen sind. Die Option <code><a href="http://de2.php.net/manual/en/ini.core.php#ini.post-max-size">post_max_size</code></a> muss ebenfalls beachtet werden, da die Dateien über das POST-Verfahren hochgeladen werden, limitiert auch diese Option die Gesamtgröße der Dateien die hochgeladen werden. Es empfiehlt sich den Wert dieser Option etwas höher einzustellen, da noch andere Formulardaten übertragen werden. </p>
<p>Außerdem gibt es noch die Option <code><a href="http://de2.php.net/manual/en/ini.core.php#ini.file-uploads">file_uploads</a></code>, ist diese auf off eingestellt, ist es gar nicht möglich, Dateien hochzuladen.</p>
<p>Zusätzlich muss auch die <code><a href="http://de2.php.net/manual/de/info.configuration.php#ini.max-input-time">max_input_time</a></code> beachtet werden, welche angibt wie lange PHP für das Auswerten von POST/GET/REQUEST-Daten brauchen darf. Da das Hochladen von Dateien durchaus lange dauern kann, beispielsweise wenn die Datei sehr groß ist, oder wenn der Benutzer eine langsame Verbindung hat (ISDN, langsame DSL-Verbindungen).</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; Ist das Hochladen von Dateien erlaubt?
file_uploads = On 
; Maximale Gesamtgroesse der Dateien die hochgeladen werden
; K = Kilobyte, M = Megabyte, G = Gigabyte.
upload_max_filesize = 100M 
; Maximale Groesse mittels des POST-Verfahrens uebermittelter Daten
post_max_size = 102M 
; Wie lange darf PHP fuer die Auswertung von uebermittelten Daten brauchen?
max_input_time = 3600 ; 1 Stunde</pre></div></div>

<p>Wenn die Dateien noch weiter verarbeitet werden, also beispielsweise Vorschaubilder erstellt werden o.Ä. muss eventuell auch noch die <code><a href="http://de2.php.net/manual/de/info.configuration.php#ini.max-execution-time">max_execution_time</a></code> beachtet werden. Diese gibt an, wie lange PHP-Skripte rechnen dürfen bzw. wie viel Prozessorzeit sie verbrauchen dürfen bevor sie beendet werden. Die Zeit die für Systemaufrufe, Datenbankabfragen o.Ä. aufgewendet wird, fließt nicht in die Berechnung mit ein, sondern nur die Zeit in der das PHP-Skript selbst ausgeführt wird.</p>
<h2>Mehrere Dateien auf einmal hochladen</h2>
<p>Es ist auch problemlos möglich, mehrere Dateien auf einmal hochzuladen. Dazu fügt man im Formular einfach weitere <code>input</code>-Elemente vom Typ <code>file</code> hinzu. Eine kleine Besonderheit gibt es allerdings zu beachten: Wenn man den Elementen einfach unterschiedliche Namen gibt, werden für jedes Element auch Elemente im <code>$_FILES</code>-Feld erstellt. Wenn man alle Elemente gleich benennt, muss hinter dem Namen <code>[]</code> stehen, das sieht dann z.B. so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;datei[]&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;datei[]&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>In diesem Fall würde PHP nur ein Element im <code>$_FILES</code>-Feld erstellen, die Unterelemente davon (name, size, type, etc.) hätten dann aber mehrere Werte/Elemente.<br />
<a href="http://www.antusblog.de/wp-content/uploads/2009/06/inhaltvonfiles.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/06/inhaltvonfiles.png" alt="Inhalt von $_FILES" title="Inhalt von $_FILES" width="512" height="532" class="aligncenter size-full wp-image-1502" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/06/10/dateien-hochladen-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quelltexte dokumentieren mit PhpDocumentor</title>
		<link>http://www.antusblog.de/2009/06/02/php-quelltexte-dokumentieren-mit-phpdocumentor/</link>
		<comments>http://www.antusblog.de/2009/06/02/php-quelltexte-dokumentieren-mit-phpdocumentor/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 19:58:15 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[DocBlock]]></category>
		<category><![CDATA[Dokumentation]]></category>
		<category><![CDATA[PhpDocumentor]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Quelltext]]></category>
		<category><![CDATA[Verständlichkeit]]></category>
		<category><![CDATA[Wiederverwendbarkeit]]></category>

		<guid isPermaLink="false">http://www.antusblog.de/?p=1424</guid>
		<description><![CDATA[Bei umfangreicheren PHP-Projekten ist es wichtig, das der Quelltext gut dokumentiert ist. So weiß man auch später noch, welche Funktion oder Klasse wofür zuständig ist, und wo man was findet. Wenn man im Team arbeitet oder andere Personen den Quelltext verwenden sollen, kommt man um eine Dokumentation gar nicht mehr herum. Eine gute Dokumentation erhöht [...]]]></description>
			<content:encoded><![CDATA[<p>Bei umfangreicheren PHP-Projekten ist es wichtig, das der Quelltext gut dokumentiert ist. So weiß man auch später noch, welche Funktion oder Klasse wofür zuständig ist, und wo man was findet. Wenn man im Team arbeitet oder andere Personen den Quelltext verwenden sollen, kommt man um eine Dokumentation gar nicht mehr herum. Eine gute Dokumentation erhöht die Wiederverwendbarkeit und die Verständlichkeit eines Quelltextes.</p>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/dokumentationderklassefilm.png"><img class="aligncenter size-full wp-image-1427" title="Eine Beispieldokumentation für eine Klasse, erstellt mit PhpDocumentor" src="http://www.antusblog.de/wp-content/uploads/2009/06/dokumentationderklassefilm.png" alt="Eine Beispieldokumentation für eine Klasse, erstellt mit PhpDocumentor" width="470" height="325" /></a><br />
<span id="more-1424"></span><br />
Der <strong>PhpDocumentor</strong> durchsucht Dateien nach Klassen, Funktionen, Konstanten und Variablen und erstellt automatisch eine Dokumentation. Mit sog. DocBlocks kann man die einzelnen Programmelemente direkt im Quelltext beschreiben, der PhpDocumentor fügt die Informationen aus den DocBlocks dann in der Dokumentation zur entsprechenden Klasse, Funktion, o.Ä. hinzu.</p>
<p>Dadurch, dass die Dokumentation direkt im Quelltext geschieht, entstehen einige Vorteile. Die Dokumentation ist immer auf dem neusten Stand, was bei einer separaten Dokumentation nicht unbedingt der Fall ist. Außerdem ist sie immer vollständig, denn auch wenn man zu einem Element keine Beschreibung geschrieben hat, sind zumindest einige Informationen die PhpDocumentor aus dem Quelltext ausgelesen hat, in der Dokumentation enthalten.</p>
<p><strong>Die wichtigsten Vorteile von PhpDocumentor:</strong></p>
<ul>
<li>Die Dokumentation wird automatisch erstellt, PhpDocumentor nimmt einem viel Arbeit ab.</li>
<li>Sie bleibt immer auf dem neusten Stand und ist immer vollständig.</li>
<li>Dadurch das die Dokumentation direkt im Quelltext ist, sieht man auch beim Bearbeiten des Quelltextes sofort, was z.B. eine bestimmte Funktion macht.</li>
<li>Es ist auch möglich auf Anleitungen zu verlinken oder Code in die Dokumentation einzubinden.</li>
<li>Die Dokumentation kann in viele verschiedene Formate exportiert werden, z.B. als PDF oder CHM (Windows-Hilfedatei). Wenn man die Dokumentation im HTML-Format speichert, hat man die Wahl zwischen 15 verschiedenen Smarty-Vorlagen, und es ist auch möglich eigene Vorlagen oder Exporter zu schreiben.</li>
</ul>
<p>Ein Beispiel einer komplett mit DocBlocks dokumentierten Datei findet sich <a href="http://www.antusblog.de/demos/3-quelltexte-dokumentieren-mit-phpdocumentor/beispiel.phps">hier</a>.</p>
<h2>Installation</h2>
<p>Es gibt zwei Möglichkeiten PhpDocumentor zu installieren, entweder über <a href="http://pear.php.net/">PEAR</a>, oder indem man es runterlädt und entpackt. Erstere ist einfacher. Wenn man kein PEAR hat, oder aus irgendeinem anderen Grund lieber die zweite Installationsvariante vorzieht: In der PhpDocumentor-Dokumentation findet sich eine Anleitung zur <a href="http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html#installation.sf">Installation ohne PEAR</a>.</p>
<h3>Installation mittels PEAR</h3>
<p>Wenn man PhpDocumentor über die Kommandozeile verwenden möchte, genügt folgender Befehl zur Installation:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pear <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">--alldeps</span> PhpDocumentor</pre></div></div>

<p>Will man auch die Weboberfläche verwenden, muss vorher die Option <code>data_dir</code> der PEAR-Konfiguration verändert werden. Sie muss so angepasst werden, das sie den Pfad zum Dokumente-Verzeichnis des Webservers, das ist das Verzeichnis in dem die Webseiten/PHP-Skripte/etc. liegen, enthält.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pear config-set data_dir <span style="color: #000000; font-weight: bold;">/</span>pfad<span style="color: #000000; font-weight: bold;">/</span>zum<span style="color: #000000; font-weight: bold;">/</span>htdocs<span style="color: #000000; font-weight: bold;">/</span>verzeichnis<span style="color: #000000; font-weight: bold;">/</span>pear<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Anschließend installiert man PhpDocumentor mit obigem Befehl. Nun kann man auch die Weboberfläche verwenden, diese ist, wenn man obigen Befehl verwendet, unter <code>http://localhost/pear/PhpDocumentor</code> zu erreichen.</p>
<h2>Die Benutzung von PhpDocumentor</h2>
<p>Wenn PhpDocumentor angewiesen wird, ein Projekt zu dokumentieren, werden automatisch alle Elemente wie  Klassen, Funktionen, Variablen und Konstanten aus den Dateien ausgelesen und eine Übersicht erstellt. Eine solche Übersicht ist zwar hilfreich, sie ist aber noch viel nützlicher wenn die Funktion und die Eigenschaften der einzelnen Elemente noch näher erklärt werden.</p>
<p>Dazu verwendet man sog. DocBlocks, das sind spezielle Kommentare, die von PhpDocumentor ausgewertet werden. Ein DocBlock sieht aus wie ein mehrzeiliger Kommentar, wird aber mit <code>/**</code> anstatt von <code>/*</code> eingeleitet, und vor jeder Zeile steht ein Sternchen. Ein DocBlock bezieht sich immer auf das darauffolgende Element. Die erste Zeile ist eine kurze Beschreibung des Elements, durch eine Leerzeile getrennt kann auch noch eine längere Beschreibung geschrieben werden. Darauf können dann noch einige Parameter folgen die weitere Informationen geben.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #009933; font-style: italic;">/**
   * Aendert den Namen des Films.
   * @param    string   $neuerName Der neue Name des Films.
   * @return   boolean  true bei Erfolg, false wenn ein Fehler aufgetreten ist.
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> aendereName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$neuerName</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$neuerName</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// liefert true bei Erfolg, false bei Fehlern.</span>
    <span style="color: #000088;">$ergebnis</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$datenbank</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">aendere</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">filmId</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$neuerName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$ergebnis</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Im Beispiel folgen auf die Beschreibung der Funktion noch die beiden Parameter <code>param</code> und <code>return</code>, ersterer beschreibt einen Parameter der Funktion, letzterer den Rückgabewert. Ein Parameter beginnt immer mit einem @-Zeichen. Der entsprechende Teil der Dokumentation könnte dann zum Beispiel so aussehen:<br />
<a href="http://www.antusblog.de/wp-content/uploads/2009/06/dokumentationderfunktionaenderename.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/06/dokumentationderfunktionaenderename.png" alt="Beispiel anhand der Funktion aendereName" title="Beispiel anhand der Funktion aendereName" width="456" height="238" class="aligncenter size-full wp-image-1432" /></a><br />
PhpDocumentor erstellt eine Übersicht aller im Projekt vorkommenden Elemente und Dateien. Jedes Element lässt sich dabei auch noch in Kategorien, Pakete und Unterpakete einteilen, wodurch die Dokumentation etwas übersichtlicher wird. So könnte die Klasse Film beispielsweise Teil des Pakets Video sein, welches wiederum Teil von Medienbibliothek ist.</p>
<p>Es ist auch möglich den Autor eines Codes anzugeben, so weiß man, wen man ansprechen kann, wenn man eine Frage hat. Auch Informationen zum Urheberrecht lassen sich in den Quelltext einbauen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Stellt einen Film-Eintrag in der Bibliothek dar.
 *
 * Die Klasse Film bietet Funktionen für den Zugriff auf
 * die in der Bibliothek enthaltenen Informationen ueber
 * den Film.
 *
 * @author     Max Mustermann &lt;maxmustermann@example.de&gt;
 * @package    Medienbibliothek
 * @subpackage Video
 * @version    1.23
 * @copyright  Copyright (c) 2009 Max Mustermann
 * @todo       Die Funktion loeschen() funktioniert noch nicht richtig!
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Film <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/todoliste.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/06/todoliste.png" alt="PhpDocumentor erstellt auch eine Todo-Liste." title="PhpDocumentor erstellt auch eine Todo-Liste." width="170" height="140" class="alignright size-full wp-image-1454" /></a>Sehr praktisch ist auch der Parameter todo, mit dem man Hinweise auf unfertige Funktionen, Fehler, oder andere Dinge die noch zu erledigen sind, geben kann.</p>
<p>Mit dem Parameter access ist es auch möglich festzulegen ob das Element in der Dokumentation vorkommen soll, so können zum Beispiel interne Funktionen einer Bibliothek ausgeblendet werden, die den Endanwender nicht interessieren. Für die Entwickler der Bibliothek kann dann eine separate Dokumentation generiert werden, welche diese Elemente dann auch enthält.</p>
<h3>Eine Übersicht der wichtigsten Parameter</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Beispiel</th>
<th>Funktion</th>
</tr>
</thead>
<tbody>
<tr>
<td>@access</td>
<td>@access private</td>
<td>Legt fest ob das Element in der Dokumentation vorkommen soll, standardmäßig public (wird angezeigt). Die Option private sorgt dafür, dass es nicht angezeigt wird.</td>
</tr>
<tr>
<td>@author</td>
<td>@author Max Mustermann &lt;mmustermann@example.de></td>
<td>Der Autor des Codes.</td>
</tr>
<tr>
<td>@category, @package, @subpackage</td>
<td>@package Medienbibliothek</td>
<td>Teilt das Projekt in mehrere Pakete ein, wodurch die Dokumentation übersichtlicher wird.</td>
</tr>
<tr>
<td>@copyright</td>
<td>@copyright Copyright (c) 2009 Max Mustermann</td>
<td>Informationen zum Urheberrecht.</td>
</tr>
<tr>
<td>@deprecated</td>
<td>@deprecated Bitte neue_funktion() benutzen.</td>
<td>Kennzeichnet das Element als veraltet.</td>
</tr>
<tr>
<td>@param</td>
<td>@param integer|float $zahl Eine Zahl.</td>
<td>Beschreibt einen Parameter, die erste Option gibt den erwarteten Typ an, die zweite den Namen des Parameters, der Rest ist die Beschreibung.</td>
</tr>
<tr>
<td>@var</td>
<td>@var string</td>
<td>Beschreibt den Datentyp einer Variable</td>
</tr>
</tbody>
</table>
<p>Eine Übersicht aller verfügbaren Parameter gibt es in der <a href="http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.pkg.html">Dokumentation von PhpDocumentor</a>.</p>
<h3>Code einbinden</h3>
<p>Manchmal möchte man eine Funktion oder Klasse direkt an einem Beispiel beschreiben, auch das ist kein Problem, denn mit dem <code>&lt;code&gt;</code>-Element lässt sich auch Quelltext direkt in die Beschreibung einbinden.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
   * Loescht den Film aus der Datenbank
   *
   * Diese Funktion wird wie folgt benutzt:
   * &lt;code&gt;
   * $ergebnis = $film-&gt;loeschen();
   * if (!$ergebnis) echo &quot;Film konnte nicht geloescht werden!&quot;;
   * &lt;/code&gt;
   * Und so weiter ...
   */</span></pre></div></div>

<h3>Externe Dokumentation</h3>
<p>Bei sehr langen Beschreibungen ist es sinnvoll, diese auszulagern. Der Quelltext würde ziemlich unübersichtlich werden, wenn mittendrin umfassende Anleitungen zur Benutzung von bestimmten Funktionen oder Klassen stehen würden. Dazu können die Parameter @link und @tutorial verwendet werden. Wie das funktioniert wird im <a href="http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tutorials.pkg.html">Handbuch vom PhpDocumentor</a> erklärt.</p>
<h2>Erstellen der Dokumentation</h2>
<p>Die Dokumentation kann entweder über die Kommandozeile oder über die Weboberfläche erstellt werden.</p>
<h3>Mit dem Kommandozeilen-Programm phpdoc</h3>
<p>Die Bedienung von phpdoc ist im Grunde ganz einfach, ein Beispiel:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">phpdoc <span style="color: #660033;">-t</span> dokumentation<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-d</span> meinprojekt<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Der Befehl würde alle PHP-Dateien im Verzeichnis <em>meinprojekt</em> durchgehen, eine Dokumentation daraus erstellen, und diese im Verzeichnis <em>dokumentation</em> ablegen.</p>
<p>Mit dem Parameter <code>-t &lt;Verzeichnis&gt;</code> wird also angegeben, wo die Dokumentation gespeichert werden soll, <code>-d &lt;Verzeichnis&gt;</code> gibt ein Verzeichnis (oder mehrere, durch Kommas getrennt) an, das nach PHP-Dateien durchsucht werden soll. Mit <code>-f &lt;Datei&gt;[,&lt;Datei&gt;, ...]</code> kann man noch weitere Dateien angeben, die für die Dokumentation ausgewertet werden sollen.</p>
<p>Mittels <code>-ti 'Titel der Dokumentation'</code> lässt sich der Titel festlegen, mit <code>-o &lt;Format&gt;</code> lassen sich die Ausgabeformate bestimmen. Ein Beispiel:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">phpdoc <span style="color: #660033;">-ti</span> <span style="color: #ff0000;">'Mein PHP-Projekt'</span> <span style="color: #660033;">-f</span> beispiel.php <span style="color: #660033;">-o</span> html:smarty:hands,pdf:default:default <span style="color: #660033;">-t</span> docs<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Der Befehl würde eine Dokumentation für das Projekt mit dem Namen <em>Mein PHP-Projekt</em> erstellen. Es wird nur die Datei <em>beispiel.php</em> ausgewertet, die Dokumentation wird im PDF-Format und im HTML-Format, mit der Vorlage <em>Smarty/HandS</em>, erstellt.</p>
<h3>Mit der Weboberfläche</h3>
<p><a href="http://www.antusblog.de/wp-content/uploads/2009/06/weboberflachevonphpdocumentor.png"><img src="http://www.antusblog.de/wp-content/uploads/2009/06/weboberflachevonphpdocumentor.png" alt="Das Menü der Weboberfläche von PhpDocumentor" title="Das Menü der Weboberfläche von PhpDocumentor" width="450" height="40" class="aligncenter size-full wp-image-1445" /></a><br />
Die Weboberfläche ist sogar noch einfacher zu bedienen, als die Kommandozeilen-Version. Unter <strong>Files</strong> gibt man die Dateien und Verzeichnisse an, die dokumentiert werden sollen. Unter <strong>Output</strong> wird bei <strong>Target</strong> eingetragen wo die Dokumentation gespeichert werden soll, mittels <strong>Output Format</strong> lässt sich festlegen in welchem Format (HTML, PDF, CHM, etc.) die Dokumentation erstellt werden soll, und welche Vorlage verwendet wird. Dabei ist es auch möglich gleich mehrere Ausgabeformate anzugeben. Unter <strong>Config</strong> lassen sich noch der Name des Projekts und ein paar andere Einstellungen konfigurieren. Mit einem Klick auf <em>create</em> (unten rechts) wird die Dokumentation erstellt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/06/02/php-quelltexte-dokumentieren-mit-phpdocumentor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dateien einbinden/inkludieren</title>
		<link>http://www.antusblog.de/2009/05/30/dateien-einbinden-inkludieren-2/</link>
		<comments>http://www.antusblog.de/2009/05/30/dateien-einbinden-inkludieren-2/#comments</comments>
		<pubDate>Sat, 30 May 2009 21:34:50 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dateien]]></category>
		<category><![CDATA[Einbinden]]></category>
		<category><![CDATA[include]]></category>
		<category><![CDATA[include_once]]></category>
		<category><![CDATA[Inkludieren]]></category>
		<category><![CDATA[require]]></category>
		<category><![CDATA[require_once]]></category>

		<guid isPermaLink="false">http://antusblog.de/?p=1379</guid>
		<description><![CDATA[Wie in vielen anderen Programmiersprachen auch, kann man in PHP Code aus anderen Dateien in den Quelltext einbinden. So können längere Quelltexte aufgeteilt oder zum Beispiel Klassen oder Funktionen in eigene Dateien ausgelagert werden. Mittels der include-Anweisung können diese Dateien dann in den Quelltext eingebunden werden. Wie das Inkludieren funktioniert und welche Anweisungen zum Einbinden [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://antusblog.de/wp-content/uploads/2009/05/phpdateieneinbinden.png"><img src="http://antusblog.de/wp-content/uploads/2009/05/phpdateieneinbinden.png" alt="Dateien Inkludieren mit PHP" title="Dateien Inkludieren mit PHP" width="150" height="100" class="alignright size-full wp-image-1420" /></a>Wie in vielen anderen Programmiersprachen auch, kann man in PHP Code aus anderen Dateien in den Quelltext einbinden. So können längere Quelltexte aufgeteilt oder zum Beispiel Klassen oder Funktionen in eigene Dateien ausgelagert werden. Mittels der include-Anweisung können diese Dateien dann in den Quelltext eingebunden werden. Wie das Inkludieren funktioniert und welche Anweisungen zum Einbinden von Dateien es noch gibt, erkläre ich in diesem Artikel.<br />
<span id="more-1379"></span><br />
Eine <code>include</code>-Anweisung sieht beispielsweise so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">hallo.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Hallo&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'welt.php'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
welt.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot; Welt!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Wenn man die <em>hallo.php</em> nun aufruft, würde <em>Hallo Welt!</em> ausgegeben werden. Der Inhalt der <em>welt.php</em> wurde an der Stelle von <code>include 'welt.php'</code> eingefügt (auch: inkludiert, oder eingebunden).</p>
<p>Die include-Anweisung ist ein Sprachkonstrukt, und keine Funktion! Deswegen kann sie auch ohne Klammern geschrieben werden, das sollte man sich auch angewöhnen, denn es gibt Fälle in denen die Klammern weggelassen werden müssen.</p>
<h2>Anweisungen zum Einbinden von Dateien</h2>
<p>Es gibt 4 Anweisungen zum Einbinden von Dateien: <code>include</code>, <code>require</code>, <code>include_once</code> und <code>require_once</code>. </p>
<ul>
<li>Wenn eine mittels <code>include</code> eingebundene Datei nicht gefunden wurde, wird eine Warnung ausgegeben. Wurde die Datei mittels <code>require</code> eingebunden, wird zusätzlich zu der Warnung noch ein Fataler Fehler ausgegeben, wodurch die Skriptausführung abgebrochen wird.</li>
<li><code>include_once</code> und <code>require_once</code> inkludieren eine Datei nur wenn sie noch nicht inkludiert wurde, das ist nützlich um zu vermeiden das Variablen, Funktionen oder Klassen mehrmals definiert werden (was zu einem Fehler führen würde).</li>
</ul>
<h2>Funktionsweise: Inkludieren</h2>
<p>Wenn eine Datei inkludiert wird, springt der PHP-Interpreter am Anfang der inkludierten Datei aus dem Parse-Modus raus, und setzt das Parsen erst am Ende der inkludierten Datei fort. Wenn man also PHP-Quelltext inkludieren möchte, muss man auch in der zu inkludierenden Datei Start- und Endtags (<code><&#63;php</code> und <code>?></code>) einfügen, ansonsten wird der Quelltext vom PHP-Interpreter nicht interpretiert (also nur ausgegeben).</p>
<p>Wenn bei der Interpretation der inkludierten Datei ein Fehler auftritt, beispielsweise aufgrund eines Syntax-Fehlers (z.B. einem vergessenen Semikolon), wird die Ausführung des kompletten Skripts beendet.</p>
<h3>Der include_path</h3>
<p>Der <code>include_path</code> gibt an, wo PHP die zu inkludierende Datei suchen soll, dabei können auch mehrere Pfade angegeben werden. Wenn eine Datei inkludiert wird, sucht PHP sie unter den im <code>include_path</code> angegebenen relativen Pfaden, zuerst relativ zum Arbeitsverzeichnis, danach relativ zu dem Verzeichnis in dem sich das aktuelle Skript befindet. Danach werden die absoluten Pfade im <code>include_path</code> durchsucht.</p>
<ul>
<li>Der aktuelle include_path kann mittels der Funktion <a href="http://de.php.net/manual/de/function.get-include-path.php"><code>get_include_path()</code></a> abgefragt werden. Die Funktion liefert den/die Pfade als Zeichenkette, getrennt durch Doppelpunkte (Linux/Unix) bzw. Semikolons (Windows) zurück.	</li>
<li>Mit <code><a href="http://de.php.net/manual/de/function.set-include-path.php">set_include_path(string $pfad)</a></code> lässt sich der <code>include_path</code> ändern, die Konstante <code>PATH_SEPARATOR</code> kann verwendet werden um die einzelnen Pfade zu trennen, da ja unter Windows andere Separatoren (Semikolons) als unter Linux/Unix verwendet werden.</li>
<li>Das aktuelle Arbeitsverzeichnis lässt sich mit der Funktion <a href="http://de.php.net/manual/de/function.getcwd.php"><code>getcwd()</code></a> ermitteln. Normalerweise ist es das Verzeichnis, in dem die vom Benutzer aufgerufene Datei liegt.</li>
</ul>
<p>Ein kleines Beispiel:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">/htdocs/test/index.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">echo</span> get_cwd<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                <span style="color: #666666; font-style: italic;">// Arbeitsverzeichnis: /htdocs/test/</span>
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">get_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>       <span style="color: #666666; font-style: italic;">// include_path: .:bla:/lib/php</span>
                               <span style="color: #666666; font-style: italic;">// (also . und bla und /lib/php)</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'classes/test.php'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
htdocs/test/classes/test.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'bla.php'</span><span style="color: #339933;">;</span>             <span style="color: #666666; font-style: italic;">// (befindet sich ebenfalls in classes/)</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>In diesem Beispiel würde PHP wie folgt vorgehen:<br />
<a href="http://antusblog.de/wp-content/uploads/2009/05/dateieninkludiereninphp.png"><img src="http://antusblog.de/wp-content/uploads/2009/05/dateieninkludiereninphp.png" alt="Dateien inkludieren in PHP" title="Dateien inkludieren in PHP" width="450" height="220" class="aligncenter size-full wp-image-1413" /></a><br />
Sobald die Datei gefunden wurde, wird sie inkludiert, PHP sucht dann natürlich nicht mehr weiter.</p>
<h4>Was hat es mit . und .. auf sich?</h4>
<p>Der Punkt steht unter Unix/Linux für das aktuelle Verzeichnis, .. steht für das übergeordnete Verzeichnis. Der Pfad /test/./xyz hat die selbe Bedeutung wie /test/xyz, /test/../xyz wäre aber /xyz. Obwohl sie eigentlich aus der Unix-Welt kommen, funktionieren . und .. auch, wenn man PHP unter Windows benutzt. Übrigens: Wenn man vor den Pfad einer inkludierten Datei einen . bzw. .. setzt, wird der include_path ignoriert, PHP sucht dann relativ zum Skript-Verzeichnis nach der Datei.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'./datei_im_selben_verzeichnis.php'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'../datei_im_uebergeordneten_verzeichnis.php'</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Der Geltungsbereich von Variablen</h3>
<p>Inkludierte Dateien übernehmen den <a href="http://de.php.net/manual/de/language.variables.scope.php">Geltungsbereich</a> von der Stelle, an der sie inkludiert werden. Alles was im dortigen Geltungsbereich liegt, ist auch in der inkludierten Datei verfügbar. Variablen die in der inkludierten Datei definiert werden übernehmen ebenfalls den Geltungsbereich von der Stelle an der die Datei inkludiert wurde. Alle Klassen und Funktionen die in der inkludierten Datei definiert werden, sind aber global sichtbar.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">hallowelt.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">function</span> hallo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$hallo</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Hallo Welt!&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'ausgeben.php'</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ausgegeben</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// bool(true)</span>
<span style="color: #009900;">&#125;</span>
hallo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ausgegeben</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// NULL</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
ausgeben.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$hallowelt</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Hallo Welt!</span>
<span style="color: #000088;">$ausgegeben</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<h3>Entfernte Dateien</h3>
<p>Wenn in der PHP-Konfigurationsdatei <a href="http://de.php.net/manual/de/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a> und <a href="http://de.php.net/manual/de/filesystem.configuration.php#ini.allow-url-include">allow_url_include</a> aktiviert sind, ist es auch möglich Dateien von anderen Servern zu inkludieren. Diese Dateien werden auch von PHP interpretiert, d.h. enthaltener PHP-Quelltext wird ausgeführt!</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'http://www.example.com/skript.php'</span><span style="color: #339933;">;</span></pre></div></div>

<p>Hierbei muss man allerdings beachten, das der Server auf dem die zu inkludierende Datei liegt, den PHP-Quelltext nicht schon interpretiert bzw. das der Server auch PHP-Quelltext ausgibt. </p>
<h3>Rückgabewerte</h3>
<p>Innerhalb einer inkludierten Datei kann man wie bei Funktionen mit <a href="http://de.php.net/manual/de/function.return.php"><code>return</code></a> zurückspringen, es ist auch möglich ein Ergebnis bzw. einen Rückgabewert zu übergeben. Wenn eine inkludierte Datei keinen Rückgabewert mittels <code>return</code> zurückgibt, gibt include <code>1</code> zurück (Inkludieren erfolgreich) oder <code>false</code> (Inkludieren nicht erfolgreich, z.B. wenn die Datei nicht gefunden wurde).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">test.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$ergebnis</span> <span style="color: #339933;">=</span> <span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'berechnung.php'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$ergebnis</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 42</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
berechnung.php:
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$zahl</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">40</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$zahl</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Das hier wird nie ausgegeben.&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Bei entfernten Dateien geht das allerdings nicht (so einfach). Man kann aber auch bei entfernten Dateien Werte zurückgeben, indem man sie einfach als Variablen definiert. In inkludierten Dateien definierte Variablen sind ja auch in der Datei die sie inkludieren verfügbar.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$rueckgabewert</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">42</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Wenn man mit dem Rückgabewert einer inkludierten Datei arbeitet, sollte man darauf achten, dass man die include-Anweisung ohne Klammern schreibt, in manchen Fällen kann es sonst dazu kommen das PHP die Anweisung falsch interpretiert.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// So ist es falsch! PHP würde hier folgendes tun:</span>
<span style="color: #666666; font-style: italic;">// ('berechnung.php') mit 42 vergleichen = false (sind nicht gleich)</span>
<span style="color: #666666; font-style: italic;">// include erwartet eine Zeichenkette, false wird zu einer Zeichenkette umgewandelt,</span>
<span style="color: #666666; font-style: italic;">// dabei kommt '' (leere Zeichenkette) raus.</span>
<span style="color: #666666; font-style: italic;">// dann würde PHP versuchen '' zu inkludieren, das klappt nicht.</span>
<span style="color: #666666; font-style: italic;">// include gibt false zurück, der Code in der if-Bedingung wird nicht ausgeführt.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'berechnung.php'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ergebnis stimmt!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">// So funktioniert es richtig.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'berechnung.php'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ergebnis stimmt!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Automatisches Anhängen/Voranstellen von Dateien</h2>
<p>Man kann PHP so konfigurieren, das an jede interpretierte Datei eine Datei angehängt bzw. vorangestellt wird, als würde sie am Anfang bzw. am Ende der Datei mittels der <code>require</code>-Anweisung inkludiert werden. Dazu trägt man in der <code>php.ini</code> bei den Optionen <code>auto_prepend_file</code> (Voranstellen) bzw. <code>auto_append_file</code> (Anhängen) den Pfad zu der entsprechenden Datei ein. Der <code>include_path</code> wird beim Inkludieren der Dateien beachtet.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">; Automatically add files before or after any PHP document.
auto_prepend_file = /htdocs/header.php
auto_append_file = /htdocs/footer.php</pre></div></div>

<p>Wenn dort nichts oder <code>none</code> steht, wird keine Datei angehängt bzw. vorangestellt. </p>
<p style="padding-left:30px"><strong>Hinweis</strong>: Wenn das PHP-Skript mit der Funktion <a href="http://de.php.net/manual/de/function.exit.php"><code>exit()</code></a> beendet wird, wird keine Datei angehangen.</p>
<h2>Automatisches Nachladen von Klassen</h2>
<p>Wenn man objektorientierte Anwendungen schreibt, hat man oft viele Quelldateien, eine für jede Klasse. Am Anfang einer Datei steht meist eine lange Liste von <code>include</code>-Anweisungen, um alle benötigten Klassendefinitionen zu laden. Mit PHP 5 ist es auch möglich Klassen dynamisch nachzuladen, dazu wird die <code>__autoload</code>-Funktion verwendet. Wenn PHP bei der Interpretation des Quelltextes auf eine noch nicht definierte Klasse stößt und es eine <code>__autoload</code>-Funktion gibt, ruft es Funktion auf, in der dann die Quelldatei für die entsprechende Klasse gesucht und inkludiert wird. So spart man sich eine Menge Schreibarbeit.</p>
<p style="padding-left:30px;"><a href="http://aktuell.de.selfhtml.org/weblog/php-autoload">Automatisches Nachladen von Klassen mit PHP</a></p>
<h2>Die Geschwindigkeit</h2>
<p>Jan Walther hat in seinem PHP-Performance-Blog zwei interessante Artikel geschrieben bei deinen es um die Geschwindigkeit der Anweisungen zum Inkludieren von Dateien geht. Im ersten Artikel <a href="http://phpperformance.de/php-dateien-in-andere-scripts-einbinden/">PHP-Dateien in andere Scripts einbinden</a> analysiert er die Geschwindigkeit von include, require, include_once und require_once, und kommt zum Schluss das es keine merklichen Unterschiede gibt.</p>
<p>Im Artikel <a href="http://phpperformance.de/dateien-performant-einfuegen/">Dateien performant einfügen</a> beschreibt er die Unterschiede zwischen absoluten, semiabsoluten und relativen Pfaden, und wie sie sich auf die Geschwindigkeit auswirken. Außerdem beschreibt er eine Methode, mit der sich Dateien mit ihrem absoluten Pfad inkludieren lassen, ohne das man dabei auf die Flexibilität von relativen Pfaden verzichten muss.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/05/30/dateien-einbinden-inkludieren-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fehlerbehandlung mit Ausnahmen</title>
		<link>http://www.antusblog.de/2009/05/02/fehlerbehandlung-mit-ausnahmen/</link>
		<comments>http://www.antusblog.de/2009/05/02/fehlerbehandlung-mit-ausnahmen/#comments</comments>
		<pubDate>Sat, 02 May 2009 14:42:12 +0000</pubDate>
		<dc:creator>Antu</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ausnahmen]]></category>
		<category><![CDATA[Exceptions]]></category>
		<category><![CDATA[Fehler]]></category>
		<category><![CDATA[Fehlerbehandlung]]></category>
		<category><![CDATA[Objektorientierte Programmierung]]></category>

		<guid isPermaLink="false">http://antusblog.de/?p=1050</guid>
		<description><![CDATA[PHP bietet seit Version 5 auch eine Ausnahmebehandlung ähnlich anderen objektorientierten Programmiersprachen wie C++, Java oder Python. Die Fehlerbehandlung mittels Ausnahmen bietet gegenüber der Fehlerbehandlung mittels Rückgabewerten einige Vorteile, und ermöglicht eine übersichtlichere und flexiblere Behandlung von Fehlern. Vorteile von Ausnahmen Mit Ausnahmen lässt sich die Fehlerbehandlung vom normalen Code trennen, wodurch der Quelltext übersichtlicher [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://antusblog.de/wp-content/uploads/2009/04/exceptioncatch.png"><img class="alignright size-full wp-image-1051" title="Ausnahmen" src="http://antusblog.de/wp-content/uploads/2009/04/exceptioncatch.png" alt="Ausnahmen" width="150" height="150" /></a>PHP bietet seit Version 5 auch eine <a href="http://de.wikipedia.org/wiki/Ausnahmebehandlung">Ausnahmebehandlung</a> ähnlich anderen objektorientierten Programmiersprachen wie C++, Java oder Python. Die Fehlerbehandlung mittels <a href="http://de2.php.net/manual/de/language.exceptions.php">Ausnahmen</a> bietet gegenüber der Fehlerbehandlung mittels Rückgabewerten einige Vorteile, und ermöglicht eine übersichtlichere und flexiblere Behandlung von Fehlern.</p>
<h3>Vorteile von Ausnahmen</h3>
<ul>
<li>Mit Ausnahmen lässt sich die Fehlerbehandlung vom normalen Code trennen, wodurch der Quelltext <strong>übersichtlicher</strong> wird.</li>
<li>Ausnahmen bieten einem mehr <strong>Kontrolle</strong> und <strong>Flexibilität</strong> bei der Fehlerbehandlung. Fehler können an der Stelle im Quelltext behandelt werden, an der man am besten darauf reagieren kann.</li>
<li>Sie <strong>erleichtern die Fehlersuche</strong> und <strong>vermeiden das Übersehen von Fehlern</strong>. Bei der Fehlerbehandlung mittels Rückgabewerten kann es passieren das man vergisst einen Rückgabewert zu prüfen. Das Skript arbeitet dann einfach weiter, und es kann zu unerwarteten Ergebnissen kommen. Die Ursache solcher Fehler zu finden ist sehr schwer, besonders wenn sie nur selten oder unter bestimmten Umständen auftreten. Mit Ausnahmen kann das nicht passieren, eine nicht behandelte Ausnahme bricht die Skript-Ausführung ab.</li>
</ul>
<p><span id="more-1050"></span></p>
<h3>Ein kleines Beispiel</h3>
<p>Der folgende Quelltext gibt eine zufällige Zeile aus der Datei zitate.txt aus, zur Fehlerbehandlung wird der Rückgabewert überprüft.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> zitat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'zitate.txt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&amp;Ouml;ffnen der Datei ist fehlgeschlagen&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$zitate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$zitat</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitat</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$zitate</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$zitat</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitate</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Keine Zitate gefunden.&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$zitate</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitate</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$lustiges_zitat</span> <span style="color: #339933;">=</span> zitat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$lustiges_zitat</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$lustiges_zitat</span><span style="color: #339933;">;</span></pre></div></div>

<p>Die Funktion <code>zitat()</code> gibt eine Fehlermeldung aus und liefert den Wert NULL zurück wenn ein Fehler auftritt. Man könnte die Funktion auch so umschreiben, dass sie anstatt NULL einen Fehlercode zurückgibt. </p>
<p>Anstatt jedoch die Funktion einen Rückgabewert, der einen Fehler anzeigt, zurückgeben zu lassen kann man sie auch einfach eine Ausnahme auslösen lassen die alle für die Fehlerbehandlung benötigten Informationen enthält. Denn möglicherweise kann man innerhalb der Funktion bzw. bei deren Aufruf gar nicht angemessen auf den Fehler reagieren. Ausnahmen werden so lange an aufrufende Funktionen zurückgereicht bis sie gefangen werden. So kann den Fehler an der Stelle behandeln an der man am besten darauf reagieren kann. </p>
<p>Beispielsweise könnte man den Fehler das keine Zitate gefunden wurden an einer Stelle behandeln an der bekannt ist ob der Benutzer eingeloggt ist und neue Zitate in die Textdatei einfügen darf. Ist das der Fall könnte man zusätzlich zur Fehlermeldung noch einen Link zu einer Seite anzeigen, auf der man neue Zitate in die Datei schreiben kann.  </p>
<p>Der selbe Quelltext mit Ausnahmen zur Fehlerbehandlung könnte so aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> zitat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'zitate.txt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Konnte die Datei nicht &amp;ouml;ffnen.&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$zitate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$zitat</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitat</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$zitate</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$zitat</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitate</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Keine Zitate gefunden.&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$zitate</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zitate</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
try <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> zitat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;h1&gt;Fehler&lt;/h1&gt;&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$berechtigungen</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'zitat_hinzufuegen'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;a href=&quot;neu.php&quot;&gt;Neues Zitat hinzufügen&lt;/a&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In dieser Variante wird ein Link zum Hinzufügen neuer Zitate angezeigt wenn keine Zitate gefunden wurden. Wenn man an dieser Stelle nicht überprüfen kann ob der Benutzer überhaupt die Rechte dazu hat, könnte man die Ausnahme auch an einer anderen Stelle abfangen, an der man das überprüfen kann.</p>
<h2>Funktionsweise von Ausnahmen</h2>
<p>Eine Ausnahme wird mit dem Schlüsselwort <strong>throw</strong> &#8220;geworfen&#8221; und mit <strong>catch</strong> gefangen bzw. behandelt. Es können nur Objekte der Ausnahmeklasse Exception oder davon abgeleiteten Klassen geworfen werden.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Es ist was schiefgegangen.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jede geworfene Ausnahme muss auch irgendwo gefangen werden, ansonsten bricht die Ausführung des Skripts mit einer Fehlermeldung wie dieser ab:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Fatal error: Uncaught exception 'Exception' with 
message 'Es ist was schiefgegangen.' in /www/exception.php:37 
Stack trace: #0 {main} thrown in /www/exception.php on line 37</pre></div></div>

<p>Innerhalb eines try-Blocks werden Ausnahmen gefangen, auf einen try-Block muss immer mindestens ein catch-Block folgen welcher die Ausnahme behandelt. Es ist möglich mehrere catch-Blöcke an einen try-Block anzuhängen um verschiedene Ausnahme-Klassen verschieden zu behandeln. Ein kleines Beispiel:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SchlimmerFehler <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
try <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/* Hier der Quelltext in dem eine Ausnahme auftreten kann */</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Es ist was schiefgegangen.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Dieser Text wird niemals ausgegeben!&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
        <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> SchlimmerFehler<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Das hat nicht geklappt.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>SchlimmerFehler <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ein ganz schlimmer Fehler ist aufgetreten! &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ein Fehler ist aufgetreten: &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Wird keine Ausnahme geworfen, überspringt PHP einfach die catch-Blöcke und macht dahinter weiter. Wenn im try-Block eine Ausnahme geworfen wird, springt PHP direkt, ohne den restlichen Code im try-Block auszuführen, zum ersten catch-Block. </p>
<p>Wenn die Klasse im catch-Block mit der Klasse der geworfenen Ausnahme übereinstimmt, oder von ihr abgeleitet ist, wird der catch-Block ausgeführt, ansonsten springt PHP zum nächsten catch-Block weiter. Es wird immer nur der erste catch-Block ausgeführt der passt. </p>
<p>Es ist auch möglich innerhalb eines catch-Blocks eine Ausnahme zu werfen, und try-Blöcke können auch verschachtelt werden.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SchlimmerFehler <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> GanzSchlimmerFehler <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
try <span style="color: #009900;">&#123;</span>
	try <span style="color: #009900;">&#123;</span>
		try <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> SchlimmerFehler<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Das hat nicht geklappt.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		catch <span style="color: #009900;">&#40;</span>GanzSchlimmerFehler <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// Wird nicht ausgeführt. Dieser catch-Block wird</span>
			<span style="color: #666666; font-style: italic;">// nur ausgeführt wenn die geworfene Ausnahme ein </span>
			<span style="color: #666666; font-style: italic;">// Objekt der Klasse GanzSchlimmerFehler ist (oder</span>
			<span style="color: #666666; font-style: italic;">// von ihr abgeleitet).</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// SchlimmerFehler ist von Exception abgeleitet, also</span>
		<span style="color: #666666; font-style: italic;">// wird dieser Block ausgeführt.</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Man kann Ausnahmen auch einfach weiterwerfen.</span>
		<span style="color: #b1b100;">throw</span> <span style="color: #000088;">$e</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Hier wird die Ausnahme wieder gefangen und die Fehler-</span>
	<span style="color: #666666; font-style: italic;">// meldung wird ausgegeben.</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ein Fehler ist aufgetreten: &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>SchlimmerFehler <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Dieser catch-Block wird niemals ausgeführt. SchlimmerFehler</span>
	<span style="color: #666666; font-style: italic;">// ist von der Klasse Exception abgeleitet, und der catch-Block </span>
	<span style="color: #666666; font-style: italic;">// vor diesem hier fängt bereits alle von Exception  </span>
	<span style="color: #666666; font-style: italic;">// abgeleiteten Ausnahme-Klassen ab.</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Wie man an dem Beispiel sehen kann, ist es wichtig das die catch-Blöcke in der richtigen Reihenfolge sind. Der letzte catch-Block des Beispiels würde nie ausgeführt werden, weil der Block davor bereits alle Ausnahmen (bzw. alle der Klasse Exception und davon abgeleiteten, was allen entspricht) abfängt.</p>
<h2>Die Klasse Exception</h2>
<p>Die Ausnahmeklasse Exception bietet noch mehr als nur die Möglichkeit eine Fehlermeldung und einen Fehlercode auszugeben. Sie ist wie folgt aufgebaut.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Exception <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Unknown Exception'</span>	<span style="color: #666666; font-style: italic;">// Fehlermeldung</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$code</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>				<span style="color: #666666; font-style: italic;">// Fehlercode</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Dateiname der Datei in der die Ausnahme aufgetreten ist.</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$file</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Zeile in der die Ausnahme aufgetreten ist.</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$line</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #000088;">$code</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Formatierte Zeichenkette für die Ausgabe</span>
	<span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Diese Funktionen können nicht überschrieben werden.</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getMessage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getCode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getFile<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getLine<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getTrace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	final <span style="color: #000000; font-weight: bold;">function</span> getTraceAsString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Eine Besonderheit stellt die Funktion <code>getTrace</code> bzw. <code>getTraceAsString</code> dar. Mit ihr lässt sich der Ablauf bis zum Fehler zurückverfolgen, ein Beispiel:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">#0 /www/exception.php(4): test('Test', 123)
#1 /www/exception.php(6): test2(123)
#2 {main}</pre></div></div>

<p>Der dazugehörige Code ist folgender:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> test<span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #339933;">,</span> <span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Es ist was schiefgelaufen.&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> test2<span style="color: #009900;">&#40;</span><span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> test<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Test&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
try <span style="color: #009900;">&#123;</span> test2<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">123</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span>  <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTraceAsString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Eigene Exception-Klassen</h3>
<p>Es ist auch möglich eigene Klassen von Exception abzuleiten, und diese je nach Bedarf noch um eigene Informationen oder Funktionen zu erweitern. Man könnte beispielsweise eine Ausnahmeklasse für nicht gefundene Dateien schreiben.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> DateiNichtGefunden <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$dateiname</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dateiname</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Sicherstellen das alles richtig zugewiesen wird</span>
		parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Datei nicht gefunden&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">123</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> datei<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dateiname</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">&quot;Die Datei &amp;raquo;<span style="color: #006699; font-weight: bold;">{$this-&gt;dateiname}</span>&amp;laquo; wurde nicht gefunden.&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Man kann so viele Methoden und Eigenschaften hinzufügen wie man möchte, wichtig ist nur das man im Konstruktor am Ende <code>parent::__construct($fehlermeldung, $fehlercode);</code> aufruft, damit sichergestellt ist, dass alle Daten korrekt zugewiesen werden.</p>
<h2>Ungefangene Ausnahmen behandeln</h2>
<p>Wenn eine Ausnahme nicht gefangen wird, wird die Ausführung des Skripts abgebrochen und die Standardfunktion zum Behandeln von Ausnahmen aufgerufen. Es ist aber auch möglich diese Standardfunktion durch eine eigene zu ersetzen.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> ungefangene_ausnahme<span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ungefangene Ausnahme: &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
set_exception_handler<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ungefangene_ausnahme'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dazu wird die Funktion <a href="http://de2.php.net/manual/de/function.set-exception-handler.php"><code>set_exception_handler('name_der_funktion')</code></a> verwendet. Wichtig ist, dass die Funktion einen Parameter annimmt (die ungefangene Ausnahme), und das sie deklariert wird bevor eine Ausnahme geworfen wird die nirgends gefangen wird. Mit <a href="http://de2.php.net/manual/de/function.restore-exception-handler.php"><code>restore_exception_handler</code></a> lässt sich die vorherige Funktion zur Ausnahmebehandlung wiederherstellen.</p>
<p>Die Standardausgabe von PHP die angezeigt wird wenn eine Ausnahme nicht gefangen wird ist ziemlich unübersichtlich, wie man diese mittels set_exception_handler etwas übersichtlicher gestalten kann beschreibt Stephan Linzner in seinem Artikel <a href="http://www.ilimitado.de/blog/programmierung/php-exceptions-formatieren/">PHP Exceptions Formatieren</a>.</p>
<h2>Wofür sind Ausnahmen nicht gedacht?</h2>
<p>Ausnahmen sollten nur verwendet werden wenn, wie der Name es schon sagt, eine Ausnahme bzw. ein Fehler auftritt. Sie sind nicht dazu gedacht den Programmablauf zu steuern! Im Normalfall sollte ein Skript komplett durchlaufen, ohne das eine Ausnahme geworfen wird.</p>
<p><em>Beispiel: Für solche Zwecke sollte man Ausnahmen <strong>nicht</strong> verwenden</em></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array_search</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$benutzername</span><span style="color: #339933;">,</span> <span style="color: #000088;">$benutzer</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">throw</span> BenutzerExistiert<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">else</span>
		<span style="color: #b1b100;">throw</span> BenutzerExistiertNicht<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
catch <span style="color: #009900;">&#40;</span>BenutzerExistiert <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
<span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p>Torsten Zander gibt in seinem Artikel <a href="http://blog.tzander.de/exceptions-fangen-und-werfen">Exceptions Fangen und Werfen</a> noch ein paar Tipps wie man Ausnahmen richtig einsetzt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.antusblog.de/2009/05/02/fehlerbehandlung-mit-ausnahmen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

