<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:series="http://organizeseries.com/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>sorgalla.com</title>
	
	<link>http://sorgalla.com</link>
	<description>PHP, Zend Framework, Datenbanken und was sonst noch so anfällt.</description>
	<lastBuildDate>Fri, 19 Apr 2013 08:15:41 +0000</lastBuildDate>
	<language>de-DE</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/sorgalla" /><feedburner:info uri="sorgalla" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>sorgalla</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Mehrere Konfigurationsdateien mit Zend_Application laden</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/V7j6Jhhe_Ao/</link>
		<comments>http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 12:01:55 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend_Application]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=519</guid>
		<description><![CDATA[Zend_Application bietet eine elegante Möglichkeit seine Zend Framework-Projekte zu initialisieren. Im Allgemeinen sieht die Instanziierung des Zend_Application-Objekts so aus: $application = new Zend_Application&#40; APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' &#41;; Das 2. Argument des Konstruktors erwartet ein Array/Zend_Config-Objekt oder häufiger, wie hier im Beispiel verwendet, einen Pfad zu einer Konfigurationsdatei. Was aber nun wenn man mehrere Konfigurationsdateien [...]]]></description>
				<content:encoded><![CDATA[<p>Zend_Application bietet eine elegante Möglichkeit seine Zend Framework-Projekte zu initialisieren. Im Allgemeinen sieht die Instanziierung des Zend_Application-Objekts so aus:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>
    APPLICATION_ENV<span style="color: #339933;">,</span>
    APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/application.ini'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Das 2. Argument des Konstruktors erwartet ein Array/Zend_Config-Objekt oder häufiger, wie hier im Beispiel verwendet, einen Pfad zu einer Konfigurationsdatei. Was aber nun wenn man mehrere Konfigurationsdateien laden möchte?<br />
<span id="more-519"></span><br />
Seit Version 1.10 erlaubt Zend_Application im Array-Argument einen Eintrag mit dem Schlüssel &#8220;config&#8221;. Der Wert kann ein Array mit beliebig vielen Pfaden zu Konfigurationsdateien sein:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>
    APPLICATION_ENV<span style="color: #339933;">,</span>
    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'config'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'/path/to/file1.ini'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'/path/to/file2.ini'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Da ich in meinen Projekten neben der normalen Webanwendung auch Kommandozeilen-Skripte habe, lassen sich so einfach zusätzliche Konfigurationsdateien für den jeweiligen Kontext laden.</p>
<p>In meiner <code>application.ini</code> stehen bei mir nur noch allgemeine Konfigurations-Optionen wie z.B. für die Datenbankverbindung oder PHP-Settings. Dazu habe ich 2 weitere Konfigurationsdateien: <code>http.ini</code> und <code>cli.ini</code>.</p>
<p>So würde bei mir die <code>application.ini</code> aus dem <a href="http://framework.zend.com/manual/en/learning.quickstart.intro.html">Quickstart</a> aufgeteilt werden:</p>
<p><strong><code>application.ini</code></strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>production<span style="">&#93;</span></span>
phpSettings.display_startup_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0</span>
phpSettings.display_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0</span>
includePaths.library <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/../library&quot;</span>
bootstrap.path <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/Bootstrap.php&quot;</span>
bootstrap.class <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;Bootstrap&quot;</span>
<span style="color: #000099;">appnamespace</span> <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;Application&quot;</span>
resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;PDO_SQLITE&quot;</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/../data/db/guestbook.db&quot;</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>staging : production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>testing : production<span style="">&#93;</span></span>
phpSettings.display_startup_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
phpSettings.display_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;PDO_SQLITE&quot;</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/../data/db/guestbook-testing.db&quot;</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>development : production<span style="">&#93;</span></span>
phpSettings.display_startup_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
phpSettings.display_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span>
resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;PDO_SQLITE&quot;</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/../data/db/guestbook-dev.db&quot;</span></pre></td></tr></table></div>

<p><strong><code>http.ini</code></strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>production<span style="">&#93;</span></span>
resources.frontController.controllerDirectory <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/controllers&quot;</span>
resources.frontController.params.displayExceptions <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0</span>
resources.layout.layoutPath <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> APPLICATION_PATH </span><span style="color: #933;">&quot;/layouts/scripts/&quot;</span>
resources.view<span style="">&#91;</span><span style="">&#93;</span> <span style="color: #000066; font-weight:bold;">=</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>staging : production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>testing : production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>development : production<span style="">&#93;</span></span>
resources.frontController.params.displayExceptions <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span></pre></td></tr></table></div>

<p>In der <code>http.ini</code> stehen die Optionen für View-, Layout-, Frontcontroller-Resourcen etc. und andere Web-spezifische Angaben.</p>
<p><strong><code>cli.ini</code></strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>staging : production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>testing : production<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>development : production<span style="">&#93;</span></span></pre></td></tr></table></div>

<p>In der <code>cli.ini</code> stehen alle CLI-spezifischen Angaben.</p>
<p>Meine <code>public/index.php</code> lädt dann <code>application.ini</code> und <code>http.ini</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// Define path to application directory</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define application environment</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'production'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Ensure library/ is on include_path</span>
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../library'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</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: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/** Zend_Application */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Application.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create application, bootstrap, and run</span>
<span style="color: #000088;">$application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>
    APPLICATION_ENV<span style="color: #339933;">,</span>
    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'config'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/application.ini'</span><span style="color: #339933;">,</span>
            APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/http.ini'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$application</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bootstrap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">run</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Und ein (mögliches) Kommandozeilen-Skript sähe dann so aus:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">#!/usr/bin/env php
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// Define path to application directory</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../application'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define application environment</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</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;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #990000;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</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;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/\/(staging|production)+\//'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</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: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'development'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Ensure library/ is on include_path</span>
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../library'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</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: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/** Zend_Application */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Application.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create application, bootstrap</span>
<span style="color: #000088;">$application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>
    APPLICATION_ENV<span style="color: #339933;">,</span>
    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'config'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/application.ini'</span><span style="color: #339933;">,</span>
            APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/cli.ini'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$application</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bootstrap</span><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;">// Do some work here</span></pre></td></tr></table></div>

<h3>Links zum Thema</h3>
<ul>
<li><a href="http://framework.zend.com/manual/de/zend.application.core-functionality.html">Dokumentation der Zend_Application-Optionen</a></li>
<li><a href="http://framework.zend.com/manual/de/learning.quickstart.html">Zend Framework Quickstart</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Mehrere+Konfigurationsdateien+mit+Zend_Application+laden+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D519+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/&amp;title=Mehrere+Konfigurationsdateien+mit+Zend_Application+laden" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/&amp;title=Mehrere+Konfigurationsdateien+mit+Zend_Application+laden" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/&amp;t=Mehrere+Konfigurationsdateien+mit+Zend_Application+laden" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/&amp;title=Mehrere+Konfigurationsdateien+mit+Zend_Application+laden" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/V7j6Jhhe_Ao" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sorgalla.com/2010/04/16/mehrere-konfigurationsdateien-mit-zend_application-laden/</feedburner:origLink></item>
		<item>
		<title>Google Code-Issues mit PHPUnit-Tests schließen und öffnen</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/lo7OO7iqA_s/</link>
		<comments>http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 12:42:51 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[GoogleCode]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[TicketListener]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=480</guid>
		<description><![CDATA[Update 25.01.2010: Sebastian Bergmann hat meine Klasse dem 3.5-Branch hinzugefügt. Sie wird also ab PHPUnit 3.5.0 standardmässig verfügbar sein. Raphael Stolt beschreibt in seinem Artikel Closing and reopening GitHub issues via PHPUnit tests wie man mit PHPUnit-Tests GitHub-Issues schließen und wieder öffnen kann. Kurz gesagt geht es dabei um test-driven bug fixing, wobei man für [...]]]></description>
				<content:encoded><![CDATA[<p class="update"><strong>Update 25.01.2010:</strong> Sebastian Bergmann <a href="http://github.com/sebastianbergmann/phpunit/blob/master/PHPUnit/Extensions/TicketListener/GoogleCode.php">hat meine Klasse dem 3.5-Branch hinzugefügt</a>. Sie wird also ab PHPUnit 3.5.0 standardmässig verfügbar sein.</p>
<p>Raphael Stolt beschreibt in seinem Artikel <a href="http://raphaelstolt.blogspot.com/2010/01/closing-and-reopening-github-issues-via.html">Closing and reopening GitHub issues via PHPUnit tests</a> wie man mit PHPUnit-Tests GitHub-Issues schließen und wieder öffnen kann. Kurz gesagt geht es dabei um <a href="http://xunitpatterns.com/test-driven%20bug%20fixing.html">test-driven bug fixing</a>, wobei man für jeden gemeldeten Bug einen Test erstellt der verifiziert, dass dieser gefixt ist. Ausführlicher kann man das in seinem <a href="http://raphaelstolt.blogspot.com/2010/01/closing-and-reopening-github-issues-via.html">Blogpost</a> nachlesen.</p>
<p>Dadurch inspiriert, habe ich einen entsprechende TicketListener für <a href="http://code.google.com/projecthosting/">Google Code</a> erstellt:<br />
<span id="more-480"></span></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> PHPUnit_Extensions_TicketListener_GoogleCode <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Extensions_TicketListener
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$email</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$password</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$project</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$statusClosed</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$statusReopened</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$printTicketStateChanges</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$authUrl</span>    <span style="color: #339933;">=</span> <span style="color: #0000ff;">'https://www.google.com/accounts/ClientLogin'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$apiBaseUrl</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://code.google.com/feeds/issues/p/%s/issues'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$authToken</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @param string $email          The email associated with the Google account.
     * @param string $password       The password associated with the Google account.
     * @param string $project        The project name of the system under test (SUT) on Google Code.
     * @param string $printTicketChanges Boolean flag to print the ticket state changes in the test result.
     * @param string $statusClosed   The status name of the closed state.
     * @param string $statusReopened The status name of the reopened state.
     * @throws RuntimeException
     */</span>
    <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;">$email</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span><span style="color: #339933;">,</span> <span style="color: #000088;">$project</span><span style="color: #339933;">,</span> <span style="color: #000088;">$printTicketStateChanges</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #339933;">,</span>
                                <span style="color: #000088;">$statusClosed</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Fixed'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$statusReopened</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Started'</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: #339933;">!</span><span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'curl'</span><span style="color: #009900;">&#41;</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> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ext/curl is not available'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">email</span>          <span style="color: #339933;">=</span> <span style="color: #000088;">$email</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">password</span>       <span style="color: #339933;">=</span> <span style="color: #000088;">$password</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">project</span>        <span style="color: #339933;">=</span> <span style="color: #000088;">$project</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusClosed</span>   <span style="color: #339933;">=</span> <span style="color: #000088;">$statusClosed</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusReopened</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$statusReopened</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">printTicketStateChanges</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$printTicketStateChanges</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiBaseUrl</span>     <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiBaseUrl</span><span style="color: #339933;">,</span> <span style="color: #000088;">$project</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @param  integer $ticketId
     * @return array
     * @throws RuntimeException
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getTicketInfo<span style="color: #009900;">&#40;</span><span style="color: #000088;">$ticketId</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</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: #339933;">!</span><span style="color: #990000;">is_numeric</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ticketId</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'status'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'invalid_ticket_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiBaseUrl</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/full/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$ticketId</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$header</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'Authorization: GoogleLogin auth='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAuthToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">callGoogleCode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$header</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: #000088;">$status</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">200</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'state'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'unknown_ticket'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$ticket</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleXMLElement<span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;xmlns=&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;ns=&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$ticket</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xpath</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'//issues:state'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$state</span>  <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$state</span> <span style="color: #339933;">===</span> <span style="color: #0000ff;">'open'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'status'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'new'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$state</span> <span style="color: #339933;">===</span> <span style="color: #0000ff;">'closed'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'status'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'closed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'status'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$state</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @param string $ticketId   The ticket number of the ticket under test (TUT).
     * @param string $statusToBe The status of the TUT after running the associated test.
     * @param string $message    The additional message for the TUT.
     * @param string $resolution The resolution for the TUT.
     * @throws RuntimeException
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> updateTicket<span style="color: #009900;">&#40;</span><span style="color: #000088;">$ticketId</span><span style="color: #339933;">,</span> <span style="color: #000088;">$statusToBe</span><span style="color: #339933;">,</span> <span style="color: #000088;">$message</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resolution</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiBaseUrl</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$ticketId</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/comments/full'</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$header</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'Authorization: GoogleLogin auth='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAuthToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'Content-Type: application/atom+xml'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$ticketStatus</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$statusToBe</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'closed'</span> ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusClosed</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusReopened</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$author</span><span style="color: #339933;">,</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">email</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'&lt;entry xmlns=&quot;http://www.w3.org/2005/Atom&quot; '</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'       xmlns:issues=&quot;http://schemas.google.com/projecthosting/issues/2009&quot;&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'  &lt;content type=&quot;html&quot;&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_COMPAT</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/content&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'  &lt;author&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'    &lt;name&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$author</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_COMPAT</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/name&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'  &lt;/author&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'  &lt;issues:updates&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'    &lt;issues:status&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ticketStatus</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_COMPAT</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/issues:status&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'  &lt;/issues:updates&gt;'</span> <span style="color: #339933;">.</span>
                <span style="color: #0000ff;">'&lt;/entry&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">callGoogleCode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$header</span><span style="color: #339933;">,</span> <span style="color: #000088;">$post</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: #000088;">$status</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">201</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> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Updating GoogleCode issue failed with status code '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">printTicketStateChanges</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Updating GoogleCode issue #<span style="color: #009933; font-weight: bold;">%d</span>, status: <span style="color: #009933; font-weight: bold;">%s</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #000088;">$ticketId</span><span style="color: #339933;">,</span>
                <span style="color: #000088;">$statusToBe</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @return string The auth token
     * @throws RuntimeException
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> getAuthToken<span style="color: #009900;">&#40;</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;">null</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">authToken</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;">authToken</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$header</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'Content-Type: application/x-www-form-urlencoded'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'accountType'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'GOOGLE'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'Email'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">email</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'Passwd'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">password</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'service'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'code'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'source'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'PHPUnit-TicketListener_GoogleCode-'</span> <span style="color: #339933;">.</span> PHPUnit_Runner_Version<span style="color: #339933;">::</span><span style="color: #004000;">id</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">callGoogleCode</span><span style="color: #009900;">&#40;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">authUrl</span><span style="color: #339933;">,</span>
            <span style="color: #000088;">$header</span><span style="color: #339933;">,</span>
            <span style="color: #990000;">http_build_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&amp;amp;'</span><span style="color: #009900;">&#41;</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: #000088;">$status</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">200</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> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Google account authentication failed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$line</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;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Auth'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'='</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">authToken</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">authToken</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> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Could not detect auth token in response'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">authToken</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @param string  $url URL to call
     * @param array   $header Header
     * @param string  $post Post data
     * @return array
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> callGoogleCode<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$header</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$curlHandle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_FOLLOWLOCATION<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_FAILONERROR<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_FRESH_CONNECT<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_HTTPPROXYTUNNEL<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_USERAGENT<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">__CLASS__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_SSL_VERIFYPEER<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>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$header</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_HTTPHEADER<span style="color: #339933;">,</span> <span style="color: #000088;">$header</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_POST<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLOPT_POSTFIELDS<span style="color: #339933;">,</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_exec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$status</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">curl_getinfo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #339933;">,</span> CURLINFO_HTTP_CODE<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: #000088;">$response</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> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #990000;">curl_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #990000;">curl_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Den TicketListener kann man z. B. in der <a href="http://www.phpunit.de/manual/current/en/appendixes.configuration.html">XML-Konfigurationsdatei</a> von PHPUnit so initialisieren:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>phpunit<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>listeners<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>listener <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;PHPUnit_Extensions_TicketListener_GoogleCode&quot;</span> <span style="color: #990000;">file</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;PHPUnit/Extensions/TicketListener/GoogleCode.php&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>arguments<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span>GOOGLE_ACCOUNT_EMAIL<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span>GOOGLE_ACCOUNT_PASSWORD<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span>GOOGLE_CODE_PROJECT_NAME<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>boolean<span style="color: #339933;">&gt;</span>true<span style="color: #339933;">&lt;/</span>boolean<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span>Fixed<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span>Started<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;/</span>arguments<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>listener<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>listeners<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>phpunit<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Die ersten 2 Argumente sind die E-Mail und das Passwort des Google-Accounts, das 3. Argument der Projektname auf Google Code, das 4. Argument ein Flag, das angibt, ob ausgegeben werden soll wenn ein sich Ticket-Status ändert und die letzten beiden Argumente die <a href="http://code.google.com/p/support/wiki/IssueTracker#Statuses_and_issue_life-cycle">Status für den Issue-Tracker</a>.</p>
<p>Den ganzen Code plus ein einfaches Demo gibts im zugehörigen <a href="http://code.google.com/p/phpunit-ticketlistener-googlecode">Google Code-Projekt</a>.</p>
<p>Dabei ist zu beachten, dass die TicketListener auf Grund eines <a href="http://www.phpunit.de/ticket/953">Bugs in der abstrakten TicketListener-Klasse</a> in der aktuellen Version von PHPUnit (3.4.6) nicht funktionieren. Deshalb sollte man vorher <a href="http://gist.github.com/281297">diesen Patch</a> anwenden.</p>
<h3>Links zum Thema</h3>
<ul>
<li><a href="http://raphaelstolt.blogspot.com/2010/01/closing-and-reopening-github-issues-via.html">Closing and reopening GitHub issues via PHPUnit tests</a></li>
<li><a href="http://code.google.com/p/phpunit-ticketlistener-googlecode">GoogleCode-TicketListener-Projekt auf Google Code</a></li>
<li><a href="http://www.phpunit.de">PHPUnit</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Google+Code-Issues+mit+PHPUnit-Tests+schlie%C3%9Fen+und+%C3%B6ffnen+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D480+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/&amp;title=Google+Code-Issues+mit+PHPUnit-Tests+schlie%C3%9Fen+und+%C3%B6ffnen" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/&amp;title=Google+Code-Issues+mit+PHPUnit-Tests+schlie%C3%9Fen+und+%C3%B6ffnen" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/&amp;t=Google+Code-Issues+mit+PHPUnit-Tests+schlie%C3%9Fen+und+%C3%B6ffnen" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/&amp;title=Google+Code-Issues+mit+PHPUnit-Tests+schlie%C3%9Fen+und+%C3%B6ffnen" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/lo7OO7iqA_s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://sorgalla.com/2010/01/24/google-code-issues-mit-phpunit-tests-schliesen-und-offnen/</feedburner:origLink></item>
		<item>
		<title>Sphinx und SphinxSE ins Zend Framework integrieren</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/rjBMIMWg2hU/</link>
		<comments>http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 10:58:05 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sphinx]]></category>
		<category><![CDATA[SphinxSE]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=424</guid>
		<description><![CDATA[Nachdem Sphinx und SphinxSE installiert ist, geht es diesmal um die Integration in ein Zend Framework-Projekt. Dazu gehört die Erstellung einer Konfigurationsdatei und ein Kommandozeilen-Skript zum Starten und Stoppen des Sphinx-Suchdämons und zum Generieren des Suchindexes. Den Code zum Artikel gibts auf github. Das Zend Framework ist nicht enthalten und muss noch nachinstalliert werden. Entweder [...]]]></description>
				<content:encoded><![CDATA[<p><a href="/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/">Nachdem Sphinx und SphinxSE installiert ist</a>, geht es diesmal um die Integration in ein Zend Framework-Projekt. Dazu gehört die Erstellung einer Konfigurationsdatei und ein Kommandozeilen-Skript zum Starten und Stoppen des Sphinx-Suchdämons und zum Generieren des Suchindexes.</p>
<p>Den Code zum Artikel gibts auf <a href="http://github.com/jsor/sphinx-and-zend-framework">github</a>.</p>
<p><span id="more-424"></span></p>
<p>Das Zend Framework ist nicht enthalten und muss noch nachinstalliert werden. Entweder man <a href="http://framework.zend.com/download/latest">lädt</a> sich die aktuelle Version herunter und kopiert oder linkt den Zend-Ordner ins <code>library</code>-Verzeichnis oder man installiert es per PEAR. Den (inoffiziellen) PEAR Channel gibts unter <a href="http://pear.zfcampus.org/">http://pear.zfcampus.org</a>.</p>
<h3>Die Konfigurationsdatei</h3>
<p>Die Konfigurationsdatei von Sphinx ist die Schaltzentrale und enthält alle Optionen für den <a href="http://www.sphinxsearch.com/docs/current.html#confgroup-searchd">Dämon</a>, den <a href="http://www.sphinxsearch.com/docs/current.html#confgroup-indexer">Indexer</a>, die <a href="http://www.sphinxsearch.com/docs/current.html#confgroup-index">Indizes</a> und deren <a href="http://www.sphinxsearch.com/docs/current.html#confgroup-source">Datenquellen</a>. Für unser Beispielprojekt nutzen wir eine einfache Variante mit Grundeinstellungen. Der Clou ist, dass die Konfigurationsdateien von jeder beliebigen Skriptsprachen verarbeitet werden kann. Einfach am Anfang der Datei den entsprechenden <a href="http://de.wikipedia.org/wiki/Shebang">Shebang</a> setzen.</p>
<p>Die Datei liegt in <code>application/configs/sphinx.conf</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">#!/usr/bin/env php
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define path to application directory</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_PATH'</span><span style="color: #339933;">,</span> <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</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: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define application environment</span>
<span style="color: #666666; font-style: italic;">//</span>
<span style="color: #666666; font-style: italic;">// Use `export APPLICATION_ENV=development` or edit /etc/environment</span>
<span style="color: #666666; font-style: italic;">// to change the application environment</span>
<span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">||</span> <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #990000;">getenv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPLICATION_ENV'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'production'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Ensure library/ is on include_path</span>
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span>PATH_SEPARATOR<span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #990000;">realpath</span><span style="color: #009900;">&#40;</span>APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../../library'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</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: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/** Zend_Application */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Application.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create application, bootstrap, and run</span>
<span style="color: #000088;">$application</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Application<span style="color: #009900;">&#40;</span>
    APPLICATION_ENV<span style="color: #339933;">,</span>
    APPLICATION_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/configs/application.ini'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$application</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOptions</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>
source posts
{
    type                    = mysql
&nbsp;
    sql_host                = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'resources'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'params'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'host'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    sql_user                = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'resources'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'params'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    sql_pass                = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'resources'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'params'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    sql_db                  = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'resources'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'params'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'dbname'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    # sql_port               = 3306    # optional, default is 3306
&nbsp;
    sql_query_pre           = SET NAMES utf8
&nbsp;
    sql_query               = \
        SELECT posts.id, posts.category_id, posts.title, posts.content, UNIX_TIMESTAMP(posts.created) AS created, \
               categories.name AS category_name, \
               GROUP_CONCAT(tags.tag SEPARATOR ', ') AS tags \
          FROM posts \
          JOIN categories ON (categories.id = posts.category_id) \
     LEFT JOIN posts_tags ON (posts_tags.post_id = posts.id) \
     LEFT JOIN tags ON (tags.id = posts_tags.tag_id) \
      GROUP BY posts.id
&nbsp;
    sql_attr_uint           = category_id
    sql_attr_timestamp      = created
&nbsp;
    sql_query_info          = \
        SELECT posts.id, posts.category_id, posts.title, posts.content, posts.created, \
               categories.name AS category_name, \
               GROUP_CONCAT(tags.tag SEPARATOR ', ') AS tags \
          FROM posts \
          JOIN categories ON (categories.id = posts.category_id) \
     LEFT JOIN posts_tags ON (posts_tags.post_id = posts.id) \
     LEFT JOIN tags ON (tags.id = posts_tags.tag_id) \
         WHERE posts.id=$id
}
&nbsp;
index posts
{
    source                  = posts
    path                    = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'index'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'path'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>/posts
    docinfo                 = extern
    html_strip              = 1
    charset_type            = utf-8
    # Character table for german (from http://www.sphinxsearch.com/forum/view.html?id=19)
    charset_table           = 0..9, A..Z-&gt;a..z, _, a..z, U+C4-&gt;U+E4, U+D6-&gt;U+F6, U+DC-&gt;U+FC, U+DF, U+E4, U+F6, U+FC
}
&nbsp;
indexer
{
    mem_limit               = 32M
}
&nbsp;
searchd
{
    listen                  = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'searchd'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'listen'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    log                     = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'searchd'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'log'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    query_log               = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'searchd'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'query_log'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    read_timeout            = 5
    max_children            = 30
    pid_file                = <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'searchd'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'pid_file'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    max_matches             = 1000
    seamless_rotate         = 1
    preopen_indexes         = 0
    unlink_old              = 1
}</pre></td></tr></table></div>

<p>Was die einzelnen Optionen bedeuten, kann man in der <a href="http://www.sphinxsearch.com/docs/current.html#conf-reference">Dokumentation</a> gut nachlesen. Ich will hier nur auf paar Besonderheiten eingehen:</p>
<ul>
<li>Der PHP-Abschnitt am Anfang der Datei nutzt <code>Zend_Application</code> um die <code>application.ini</code> zu laden.</li>
<li>Im Abschnitt <code>source posts</code> nutzen wir die ausgelesenen Optionen um die Zugangsdaten für die Datenbank zu setzen. Diese können dann global in der <code>application.ini</code> verwaltet werden.</li>
<li>Im Abschnitt <code>index posts</code> und <code>searchd </code>verwenden wir ebenfalls Optionen aus der <code>application.ini</code>. Das sind vor allem Pfadangaben für den Suchindex und Logdateien und an welcher IP und/oder Port der Suchdämon lauschen soll. Diese Angaben können wir somit pro <code>APPLICATION_ENV</code> anpassen.</li>
</ul>
<h3>Das Kommandozeilen-Skript für Sphinx</h3>
<p>Um den Suchindex zu erstellen und den Suchdämon zu starten und zu stoppen, enthält das Projekt das Kommandozeilen-Skript in <code>scripts/sphinx</code>. Der Aufruf erfolgt so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span>.<span style="color: #000000; font-weight: bold;">/</span>scripts<span style="color: #000000; font-weight: bold;">/</span>sphinx COMMAND ENVIRONMENT</pre></td></tr></table></div>

<h4>COMMAND</h4>
<table class="summary">
<caption>Folgende Kommandos sind möglich:</caption>
<tbody>
<tr>
<th>start</th>
<td>Startet den Suchdämon.</td>
</tr>
<tr>
<th>stop</th>
<td>Stoppt den Suchdämon.</td>
</tr>
<tr>
<th>restart</th>
<td>Startet den Suchdämon neu.</td>
</tr>
<tr>
<th>index-all</th>
<td>Erstellt alle in <code>application/configs/sphinx.conf</code> definierten Suchindizes.</td>
</tr>
</tbody>
</table>
<h4>ENVIRONMENT</h4>
<p>Gibt <code>APPLICATION_ENV</code> an, entspricht also <code>define('APPLICATION_ENV', 'production');</code> in z. B. der <code>index.php</code>. Somit wird der entsprechende Abschnitt in <code>application/configs/application.ini</code> genutzt. Wenn nicht angegeben, wird standardmäßig <code>production</code> verwendet.</p>
<h4>Beispiele</h4>
<p>Startet den Suchdämon mit <code>APPLICATION_ENV=production</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span>.<span style="color: #000000; font-weight: bold;">/</span>scripts<span style="color: #000000; font-weight: bold;">/</span>sphinx start production</pre></td></tr></table></div>

<p>Erstellt alle Suchindizes mit <code>APPLICATION_ENV=development</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span>.<span style="color: #000000; font-weight: bold;">/</span>scripts<span style="color: #000000; font-weight: bold;">/</span>sphinx index-all development</pre></td></tr></table></div>

<p>Somit haben wir nun unser Zend Framework-Projekt präpariert um mit Sphinx zu arbeiten. Auf den Suchindex lässt sich nun ganz einfach, z. B. per <a href="http://framework.zend.com/manual/en/zend.db.select.html">Zend_Db_Select</a>, zugreifen:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Mein Suchbegriff'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$select</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">select</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$select</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'posts'</span><span style="color: #009900;">&#41;</span>
       <span style="color: #339933;">-&gt;</span><span style="color: #004000;">joinInner</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sphinx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sphinx.id = posts.id'</span><span style="color: #009900;">&#41;</span>
       <span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sphinx.query = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$query</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">';mode=any;sort=extended:@weight desc, @id asc;limit=10;offset=0;index=posts'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$select</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>Links zum Thema</h3>
<ul>
<li><a href="http://github.com/jsor/sphinx-and-zend-framework">Beispielcode auf github</a></li>
<li><a href="http://www.sphinxsearch.com/docs/current.html#conf-reference">Dokumentation zu den Konfigurationsoptionen von Sphinx</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Sphinx+und+SphinxSE+ins+Zend+Framework+integrieren+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D424+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/&amp;title=Sphinx+und+SphinxSE+ins+Zend+Framework+integrieren" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/&amp;title=Sphinx+und+SphinxSE+ins+Zend+Framework+integrieren" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/&amp;t=Sphinx+und+SphinxSE+ins+Zend+Framework+integrieren" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/&amp;title=Sphinx+und+SphinxSE+ins+Zend+Framework+integrieren" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/rjBMIMWg2hU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[Schöner suchen mit Sphinx]]></series:name>
	<feedburner:origLink>http://sorgalla.com/2010/01/18/sphinx-und-sphinxse-ins-zend-framework-integrieren/</feedburner:origLink></item>
		<item>
		<title>Daten aus HTML-Dokumenten extrahieren mit Zend_Dom_Query</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/9bC-Bq9EWr8/</link>
		<comments>http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 18:50:24 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XPath]]></category>
		<category><![CDATA[Zend_Dom_Query]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=376</guid>
		<description><![CDATA[Steht man vor dem Problem Daten aus HTML-Dokumenten zu extrahieren, kommen einem oft als erstes reguläre Ausdrücke in den Sinn. Kore Nordmann hat jedoch bewiesen, dass es nicht möglich ist, HTML mit regulären Ausdrücken zu parsen und empfiehlt stattdessen die DOM-Extension zu nutzen. Genau diese nutzt die Zend_Dom_Query-Komponente und bietet eine einfache Möglichkeit, auf ein [...]]]></description>
				<content:encoded><![CDATA[<p>Steht man vor dem Problem Daten aus HTML-Dokumenten zu extrahieren, kommen einem oft als erstes reguläre Ausdrücke in den Sinn. Kore Nordmann hat jedoch bewiesen, dass es <a href="http://kore-nordmann.de/blog/0081_parse_html_extract_data_from_html.html">nicht möglich ist, HTML mit regulären Ausdrücken</a> zu parsen und empfiehlt stattdessen die <a href="http://php.net/manual/en/book.dom.php">DOM-Extension</a> zu nutzen.<br />
<span id="more-376"></span></p>
<p>Genau diese nutzt die <a href="http://framework.zend.com/manual/de/zend.dom.query.html">Zend_Dom_Query</a>-Komponente und bietet eine einfache Möglichkeit, auf ein (X)HTML-Dokument zuzugreifen. Neben dem Zugriff über XPath bietet die Komponente aber auch die Möglichkeit über CSS-Selektoren bestimmte Knoten aus einem Dokument zu selektieren (wie man es von <a href="http://prototypejs.org/api/utility/dollar-dollar">vielen</a> <a href="http://docs.jquery.com/Selectors">Javascript</a>-<a href="http://api.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.query">Frameworks</a> her kennt).</p>
<p>Der Konstruktor erwartet einen (X)HTML- oder XML-String. Abfragen mit CSS-Selektoren werden über die <code>query</code>-Methode gemacht welche dann ein <code>Zend_Dom_Query_Result</code>-Objekt zurückliefert.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Dom_Query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'selector'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Zend_Dom_Query_Result implements the Countable and Iterator interface</span>
<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// $node instanceof DOMElement</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<table class="summary">
<caption>Folgende Elemente können bei CSS-Selektoren verwendet werden</caption>
<tbody>
<tr>
<th>#id</th>
<td>
<p>Findet das Element mit dem angegebenen id-Attribut. Zum Beispiel alle Elemente mit der id &#8220;foo&#8221; (z. B. <code>&lt;div id="foo"&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</td>
</tr>
<tr>
<th>element</th>
<td>
<p>Findet alle Elemente mit dem angegebenen tag-Namen. Zum Beispiel alle <code>div</code>-Elemente:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</td>
</tr>
<tr>
<th>.class</th>
<td>
<p>Findet alle Elemente mit der angegebenen Klasse. Zum Beispiel alle Elemente mit der Klasse &#8220;foo&#8221; (z. B. <code>&lt;div class="foo"&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'.foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</td>
</tr>
<tr>
<th>[attribute]</th>
<td>
<p>Findet alle Elemente mit dem angegebenen Attribut. Dabei werden 3 Arten unterstützt.</p>
<p>1. Findet alle <code>div</code>-Elemente mit dem Attribut &#8220;foo&#8221; und dem Wert &#8220;bar&#8221; (z. B. <code>&lt;div foo="bar"&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'div[foo=&quot;bar&quot;]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>2.  Findet alle <code>div</code>-Elemente mit dem Attribut &#8220;foo&#8221; dessen Wert das Wort &#8220;bar&#8221; enthält (z. B. <code>&lt;div foo="bar baz"&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'div[foo~=&quot;bar&quot;]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>3. Findet alle <code>div</code>-Elemente mit dem Attribut &#8220;foo&#8221; dessen Wert den String &#8220;bar&#8221; irgendwo enthält (z. B. <code>&lt;div foo="barbaz"&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'div[foo*=&quot;bar&quot;]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</td>
</tr>
</tbody>
</table>
<p>Selektoren können auch &#8220;verkettet&#8221; werden um so Abhängigkeiten definieren.</p>
<p>Das folgende Beispiel findet alle <code>a</code>-Elemente die ein Unterelement eines Elements mit der Klasse &#8220;bar&#8221;<br />
sind, welches wiederum ein Unterelement eines Elements mit der id &#8220;foo&#8221; sein muss<br />
(z. B. <code>&lt;div id="foo"&gt;&lt;div&gt;&lt;div class="bar"&gt;&lt;p&gt;&lt;a href="#"&gt;Link&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#foo .bar a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Mit einem <code>&gt;</code> können direkte Abhängigkeiten definiert werden.</p>
<p>Das folgende Beispiel findet alle <code>a</code>-Elemente die ein direktes Kindelement des Elements mit der<br />
id &#8220;foo&#8221; sind (z. B. <code>&lt;div id="foo"&gt;&lt;a href="#"&gt;Link&lt;/a&gt;&lt;/div&gt;</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#foo &gt; a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Zend_Dom_Query ist übrigens auch fest in <a href="http://framework.zend.com/manual/de/zend.test.phpunit.html#zend.test.phpunit.testing">Zend_Test_PHPUnit_Controller_TestCase</a> integriert und bietet somit <a href="http://framework.zend.com/manual/de/zend.test.phpunit.html#zend.test.phpunit.assertions.query">CSS Selector Assertions</a>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> FooControllerTest <span style="color: #000000; font-weight: bold;">extends</span> Zend_Test_PHPUnit_Controller_TestCase
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testIndexContainsLoginForm<span style="color: #009900;">&#40;</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;">dispatch</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#login-form'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Links zum Thema</h3>
<ul>
<li><a href="http://kore-nordmann.de/blog/0081_parse_html_extract_data_from_html.html">Extracting data from HTML</a></li>
<li><a href="http://framework.zend.com/manual/de/zend.dom.query.html">Zend_Dom_Query</a></li>
<li><a href="http://framework.zend.com/manual/de/zend.test.phpunit.html#zend.test.phpunit.assertions.query">Zend_Test_PHPUnit_Controller_TestCase</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Daten+aus+HTML-Dokumenten+extrahieren+mit+Zend_Dom_Query+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D376+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/&amp;title=Daten+aus+HTML-Dokumenten+extrahieren+mit+Zend_Dom_Query" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/&amp;title=Daten+aus+HTML-Dokumenten+extrahieren+mit+Zend_Dom_Query" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/&amp;t=Daten+aus+HTML-Dokumenten+extrahieren+mit+Zend_Dom_Query" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/&amp;title=Daten+aus+HTML-Dokumenten+extrahieren+mit+Zend_Dom_Query" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/9bC-Bq9EWr8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sorgalla.com/2010/01/07/daten-aus-html-dokumenten-extrahieren-mit-zend_dom_query/</feedburner:origLink></item>
		<item>
		<title>Ajax-Applikationen mit dem Zend Framework</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/iBs4KF6YSrU/</link>
		<comments>http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 21:31:58 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=281</guid>
		<description><![CDATA[Ajax wird heute in fast jeder modernen Webanwendung genutzt, bietet doch jedes gute Javascript-Framework mittlerweile einfache Möglichkeiten XHR-Anfragen abzusetzen. In diesem Artikel soll es aber nicht um die Client-Seite gehen, sondern darum, wie man auf der Server-Seite XHR-Anfragen erkennt und entsprechend darauf reagiert (Der Einfachheit halber rede ich hier nur von Ajax, weite Teile lassen [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://de.wikipedia.org/wiki/Ajax_(Programmierung)">Ajax</a> wird heute in fast jeder modernen Webanwendung genutzt, bietet doch <a href="http://jquery.com">jedes</a> <a href="http://www.dojotoolkit.org">gute</a> Javascript-Framework mittlerweile einfache Möglichkeiten <a href="http://de.wikipedia.org/wiki/XMLHttpRequest">XHR</a>-Anfragen abzusetzen. In diesem Artikel soll es aber nicht um die Client-Seite gehen, sondern darum, wie man auf der Server-Seite XHR-Anfragen erkennt und entsprechend darauf reagiert (Der Einfachheit halber rede ich hier nur von Ajax, weite Teile lassen sich aber natürlich auch auf den Bereich <a href="http://de.wikipedia.org/wiki/Webservice">Webservices</a> übertragen).<span id="more-281"></span></p>
<h3>HTTP richtig nutzen</h3>
<p>Clients können z. B. über <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">Request-Header</a> dem Server mitteilen welches Rückgabe-Format sie erwarten oder bereits an korrekt gesetzten <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">Status-Codes</a> erkennen, ob die Anfrage fehlgeschlagen ist oder nicht. Diese Art der Kommunikation setzt voraus, dass der Server korrekt antwortet. Deshalb sollte man eingehende Request-Header überprüfen und verarbeiten und entsprechende Response-Header setzen.</p>
<table class="summary">
<caption>Allgemeine HTTP Request-Header</caption>
<tbody>
<tr>
<th>Content-Type</th>
<td>Der Content-Type der Daten die an die Applikation geschickt werden, z.B. <code>application/json</code></td>
</tr>
<tr>
<th>Accept</th>
<td>Der Content-Type den der Client in der Antwort erwartet, z. B. <code>application/json</code></td>
</tr>
<tr>
<th>Range</th>
<td>Anzahl Bytes oder Einheiten (items) die in der Antwort enthalten sein sollen. Die W3C-Spezifikation führt nur Byte-Ranges explizit aus. <code>dojox.data.JsonRestStore</code> z. B. nutzt den Range-Header für das Paging in der Form <code>Range: items=0-24</code> (<a href="http://docs.dojocampus.org/dojox/data/JsonRestStore#paging">Siehe Dokumentation</a>).</td>
</tr>
</tbody>
</table>
<table class="summary">
<caption>Allgemeine HTTP Response-Header</caption>
<tbody>
<tr>
<th>Content-Type</th>
<td>Der Content-Type der Daten die an den Client zurückgeschickt werden, z.B. <code>application/json</code></td>
</tr>
<tr>
<th>Vary</th>
<td>Der Vary-Header gibt dem Client oder Caching-Proxies Hinweise welche Header für das Caching verwendet werden sollen. Eine Resource kann verschiedene Darstellungsformen, abhängig vom gesendet Accept-Header, zurückliefern (z. B. eine Anfrage auf die URI <code>/resource/id</code> mit <code>Accept: text/html</code> liefert eine normal HTML-Seite und <code>Accept: application/json</code> auf die gleich URI liefert die Daten als JSON). Dadurch kann die URI nicht als eindeutige ID für das Caching verwendet werden. Ein <code>Vary: Accept</code> hilft dann dem Client oder Proxy die Antwort korrekt cachen zu können. Mehr dazu: <a href="http://www.subbu.org/blog/2007/12/vary-header-for-restful-applications">Vary Header for RESTful Applications</a>.</td>
</tr>
<tr>
<th>Content-Range</th>
<td>Anzahl Bytes oder Einheiten (items) die zurückgegeben werden. Analog zum oben beschriebenen Range-Header kann man folgendes Format verwenden: <code>Content-Range: items 0-24/66</code>. Dabei wird der Start- und End-Offset (0-24) und die Gesamtanzahl der verfügbaren Einheiten angeben (66).</td>
</tr>
</tbody>
</table>
<table class="summary">
<caption>Allgemeine HTTP Status-Codes</caption>
<tbody>
<tr>
<th>201 (Created)</th>
<td>Nach einem <a href="http://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-Request-Methoden">POST</a> der eine Resource erstellt hat.</td>
</tr>
<tr>
<th>204 (No Content)</th>
<td>Nach einem <a href="http://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-Request-Methoden">DELETE</a> der eine Resource gelöscht hat.</td>
</tr>
<tr>
<th>400 (Bad Request)</th>
<td>Validierungen sind fehlgeschlagen.</td>
</tr>
<tr>
<th>500 (Internal Server Error)</th>
<td>Applikations-Fehler, z. B. wenn eine Exception geworfen wurde.</td>
</tr>
</tbody>
</table>
<p>Ben Ramsey hat in seinem Blog eine <a href="http://benramsey.com/archives/http-status-100-continue/">kleine lesenswerte Reihe</a> zu HTTP Status-Codes.</p>
<h3>Request-Header verarbeiten mit einem Frontcontroller-Plugin</h3>
<p>Wir erstellen uns ein <a href="http://framework.zend.com/manual/de/zend.controller.plugins.html">Frontcontroller-Plugin</a>, welches die eingehenden Header inspiziert und manipulieren das Request-Objekt entsprechend. So können wir in unseren Action-Controllern auf gewohntem Wege über das Request-Objekt auf die Parameter zugreifen.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * @see Zend_Controller_Plugin_Abstract
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Controller/Plugin/Abstract.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @see Zend_Controller_Request_Http
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Controller/Request/Http.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @package    App_Controller
 * @subpackage App_Controller_Plugin
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> App_Controller_Plugin_HttpHandler <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Plugin_Abstract
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Called before Zend_Controller_Front enters its dispatch loop.
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> dispatchLoopStartup<span style="color: #009900;">&#40;</span>Zend_Controller_Request_Abstract <span style="color: #000088;">$request</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: #339933;">!</span><span style="color: #000088;">$request</span> instanceof Zend_Controller_Request_Http<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$vary</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>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Process Accept-Header (the format parameter will later be used by the ContextSwitch helper)</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;">$accept</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Accept'</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;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$accept</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'application/xml'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$accept</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'html'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setParam</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'format'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$vary</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Accept'</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$accept</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'application/json'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setParam</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'format'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'json'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$vary</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Accept'</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Process non-standard Content-Types</span>
        <span style="color: #000088;">$rawBody</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRawBody</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: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rawBody</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: #009900; font-weight: bold;">false</span> <span style="color: #339933;">!==</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$contentType</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type'</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;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contentType</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'application/xml'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span>
                    <span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contentType</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text/xml'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Config/Xml.php'</span><span style="color: #339933;">;</span>
                    <span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config_Xml<span style="color: #009900;">&#40;</span><span style="color: #000088;">$rawBody</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPost</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strstr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contentType</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'application/json'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Json.php'</span><span style="color: #339933;">;</span>
                    <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPost</span><span style="color: #009900;">&#40;</span>Zend_Json<span style="color: #339933;">::</span><span style="color: #004000;">decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rawBody</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Process Range-Header</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;">$range</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Range'</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;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/items=(\d+)\-(\d+)/i'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$range</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setParam</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'range_start'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setParam</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'range_end'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$vary</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Range'</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Set Vary-Header</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$vary</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><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;">// Keep existing Vary headers</span>
            <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$header</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;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$header</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: #339933;">!=</span> <span style="color: #0000ff;">'vary'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #000088;">$vary</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$header</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clearHeader</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$header</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: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            <span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Vary'</span><span style="color: #339933;">,</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">', '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$vary</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Ausgabe-Formate variieren mit dem ContextSwitch-Action-Helper</h3>
<p>Der standardmäßig im Zend Framework enthaltene <a href="http://framework.zend.com/manual/de/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch">ContextSwitch-Action-Helper</a> bietet uns die Möglichkeit für einzelne Actions verschiedene Kontexte zu definieren.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</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>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">contextSwitch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAutoJsonSerialization</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">addActionContext</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'list'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'json'</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">initContext</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;
    <span style="color: #009933; font-style: italic;">/**
     * List news items
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> listAction<span style="color: #009900;">&#40;</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: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_request<span style="color: #339933;">-&gt;</span><span style="color: #004000;">range_start</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_request<span style="color: #339933;">-&gt;</span><span style="color: #004000;">range_end</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_request<span style="color: #339933;">-&gt;</span><span style="color: #004000;">range_start</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$end</span>   <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_request<span style="color: #339933;">-&gt;</span><span style="color: #004000;">range_end</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$paginator</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$newsModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getItemsAsZendPaginatorObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$paginator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTotalItemCount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$limit</span> <span style="color: #339933;">=</span> <span style="color: #339933;">!</span><span style="color: #000088;">$end</span> ? <span style="color: #000088;">$count</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$start</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$end</span>   <span style="color: #339933;">=</span> <span style="color: #339933;">!</span><span style="color: #000088;">$end</span> ? <span style="color: #000088;">$count</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$end</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$paginator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getItems</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$start</span><span style="color: #339933;">,</span> <span style="color: #000088;">$limit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">// Set Content-Range-Header</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_response
                <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpResponseCode</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">206</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// Partial content header</span>
                <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Range'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'items '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$start</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'-'</span><span style="color: #339933;">.</span> <span style="color: #000088;">$end</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</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;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$newsModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAllItems</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Wir haben in diesem Controller also für die Aktion <code>listAction</code> den zusätzlichen Kontext <code>json</code> definiert und präparieren sie so für die Verwendung per Ajax.</p>
<p>Ein &#8220;context switch&#8221; wird durch den <code>format</code>-Request-Parameter augelöst. Der Parameter wird hier durch unser Plugin gesetzt, kann aber natürlich auch über die URL definiert werden (z. B. <code>/news/list/format/json</code>).  Ist der <code>format</code>-Parameter nun also auf <code>json</code> gesetzt, wird automatisch der Kontext-Name an das View-Skript angehängt. Es wird statt <code>list.phtml</code> das View-Skript <code>list.<strong>json</strong>.phtml</code> gerendert. Außerdem wird der entsprechende Content-Type-Header <code>application/json</code> gesetzt und das Rendern der Layouts deaktiviert.</p>
<p>Ein kleiner Hinweis zum JSON-Kontext: Standardmäßig wird kein View-Skript gerendert sondern es werden einfach alle dem View-Objekt zugewiesenen Variablen serialisiert und direkt ausgegeben. Dieses Verhalten haben wir oben mit <code>setAutoJsonSerialization(false)</code> deaktiviert um eine bessere Kontrolle über die Ausgabe per View-Skript zu haben.</p>
<p>Das View-Skript <code>list.json.phtml</code> kann z. B. so aussehen:</p>

<div class="wp_syntax"><table><tr><td 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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">json</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">items</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toArray</span><span style="color: #009900;">&#40;</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></td></tr></table></div>

<p>Neben dem ContextSwitch-Helper gibt auch noch den AjaxContext-Helper. Der einzige Unterschied ist, dass dieser nur bei einer Anfrage per Ajax ausgeführt wird (d. h. wenn der Header <code>X-Requested-With: XMLHttpRequest</code> gesetzt ist).</p>
<h3>RESTvolle Controller</h3>
<p>Ein weitere Möglichkeit per Ajax mit der Applikation zu kommunizieren ist <a href="http://de.wikipedia.org/wiki/Representational_State_Transfer">REST</a>. Das Zend Framework bietet dafür <a href="http://framework.zend.com/manual/de/zend.controller.router.html#zend.controller.router.routes.rest">Zend_Rest_Route</a>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$router</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addRoute</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'rest'</span><span style="color: #339933;">,</span>
    <span style="color: #000000; font-weight: bold;">new</span> Zend_Rest_Route<span style="color: #009900;">&#40;</span><span style="color: #000088;">$frontcontroller</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: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'news'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Damit haben wir den <code>NewsController</code> im <code>default</code>-Modul &#8220;RESTvoll&#8221; gemacht. Der Controller erweitert dann <a href="http://framework.zend.com/manual/de/zend.controller.router.html#zend.rest.controller">Zend_Rest_Controller</a> und muss dabei die Methoden indexAction(), getAction(), postAction(), putAction() und deleteAction() implementieren.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Rest_Controller
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * The index action handles index/list requests; it should respond with a
     * list of the requested resources.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * The get action handles GET requests and receives an 'id' parameter; it
     * should respond with the server resource state of the resource identified
     * by the 'id' value.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * The post action handles POST requests; it should accept and digest a
     * POSTed resource representation and persist the resource state.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> postAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * The put action handles PUT requests and receives an 'id' parameter; it
     * should update the server resource state of the resource identified by
     * the 'id' value.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> putAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * The delete action handles DELETE requests and receives an 'id'
     * parameter; it should update the server resource state of the resource
     * identified by the 'id' value.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> deleteAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Der Vorteil hierbei ist, dass wir ein vorhersagbares API bereitstellen. Dojo zum Beispiel bietet mit der Kombination <a href="http://docs.dojocampus.org/dojox/data/JsonRestStore">dojox.data.JsonRestStore</a> und <a href="http://docs.dojocampus.org/dojox/grid/DataGrid">dojox.grid.DataGrid</a> alles was man zur Implementierung von <a href="http://de.wikipedia.org/wiki/CRUD">CRUD</a>-Operationen braucht.</p>
<h3>Links zum Thema</h3>
<ul>
<li><a href="http://www.slideshare.net/weierophinney/architecting-ajax-applications-with-zend-framework">Architecting Ajax Applications with Zend Framework</a></li>
<li><a href="http://framework.zend.com/manual/de/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch">ContextSwitch-Action-Helper</a></li>
<li><a href="http://framework.zend.com/manual/de/zend.controller.router.html#zend.controller.router.routes.rest">Zend_Rest_Route</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Ajax-Applikationen+mit+dem+Zend+Framework+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D281+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/&amp;title=Ajax-Applikationen+mit+dem+Zend+Framework" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/&amp;title=Ajax-Applikationen+mit+dem+Zend+Framework" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/&amp;t=Ajax-Applikationen+mit+dem+Zend+Framework" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/&amp;title=Ajax-Applikationen+mit+dem+Zend+Framework" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/iBs4KF6YSrU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://sorgalla.com/2009/12/30/ajax-applikationen-mit-dem-zend-framework/</feedburner:origLink></item>
		<item>
		<title>Sphinx und SphinxSE unter Ubuntu installieren</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/JPh5YSXKVUE/</link>
		<comments>http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 18:18:27 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Sphinx]]></category>
		<category><![CDATA[SphinxSE]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=168</guid>
		<description><![CDATA[Wer Projekte mit MySQL als Datenbank-Backend realisiert, wird die Erfahrung schon gemacht haben, dass er bei der Implementierung einer Suchfunktion an Grenzen stößt. Der Fulltext-Index ist nicht der Wahrheit letzter Schluss und andere Lösungen oft nur unbefriedigende Workarounds. Hier kann Sphinx Abhilfe schaffen. Besonders die nahtlose Integration in MySQL sticht hier als Pluspunkt heraus. So [...]]]></description>
				<content:encoded><![CDATA[<p>Wer Projekte mit <a href="http://mysql.com">MySQL</a> als Datenbank-Backend realisiert, wird die Erfahrung schon gemacht haben, dass er bei der Implementierung einer Suchfunktion an Grenzen stößt. Der <a href="http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html">Fulltext-Index</a> ist nicht der Wahrheit letzter Schluss und andere Lösungen oft nur unbefriedigende Workarounds.</p>
<p>Hier kann <a href="http://www.sphinxsearch.com">Sphinx</a> Abhilfe schaffen. Besonders die nahtlose Integration in MySQL sticht hier als Pluspunkt heraus. So kann man den <a href="http://www.sphinxsearch.com/docs/current.html#sphinxse-using">Suchindex direkt über SQL-Abfragen</a> ansprechen und andere Tabellen hinzu-&#8221;joinen&#8221;.  In diesem Artikel wollen wir uns mit der Installation von Sphinx und SphinxSE, der Storage-Engine für MySQL, beschäftigen.<br />
<span id="more-168"></span><br />
Die Installationsanleitung bezieht sich auf Ubuntu 9.10 als Betriebssystem, lässt sich aber im Prinzip auch für andere Systeme/Versionen nachvollziehen. Folgende Versionen waren zum Zeitpunkt der Erstellung dieses Artikels aktuell:</p>
<ul>
<li>MySQL 5.1.37</li>
<li>Sphinx 0.9.9</li>
</ul>
<p>Wir gehen davon aus, dass MySQL bereits installiert ist, falls nicht, schnell nachholen:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> mysql-server-<span style="color: #000000;">5.1</span></pre></td></tr></table></div>

<h3>Sphinx installieren</h3>
<p>Zuerst holen wir uns die Quellen von Sphinx und entpacken Sie:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>www.sphinxsearch.com<span style="color: #000000; font-weight: bold;">/</span>downloads<span style="color: #000000; font-weight: bold;">/</span>sphinx-0.9.9.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xvzf</span> sphinx-0.9.9.tar.gz
$ <span style="color: #7a0874; font-weight: bold;">cd</span> sphinx-0.9.9<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

<p>Da wir mit <code>libstemmer</code>-Support kompilieren wollen, um deutsches <a href="http://de.wikipedia.org/wiki/Stemming">Stemming</a> nutzen zu können (Standardmäßig unterstützt Sphinx nur Englisch und Russisch), holen und entpacken wir uns noch das entprechende Archiv:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>snowball.tartarus.org<span style="color: #000000; font-weight: bold;">/</span>dist<span style="color: #000000; font-weight: bold;">/</span>libstemmer_c.tgz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xvzf</span> libstemmer_c.tgz</pre></td></tr></table></div>

<p>Nun <a href="http://www.sphinxsearch.com/docs/current.html#installing">installieren</a>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--with-libstemmer</span>
$ <span style="color: #c20cb9; font-weight: bold;">make</span>
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></td></tr></table></div>

<p>Für die weitere Konfiguration verweise ich jetzt einfach mal auf die <a href="http://www.sphinxsearch.com/docs/">Dokumentation</a> und den <a href="http://www.sphinxsearch.com/docs/current.html#quick-tour">Quickstart</a> von Sphinx.</p>
<h3>SphinxSE installieren</h3>
<p>Wir wechseln zuerst ins Elternverzeichnis und holen uns die Quellen von MySQL:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> ..<span style="color: #000000; font-weight: bold;">/</span>
$ <span style="color: #c20cb9; font-weight: bold;">apt-get <span style="color: #7a0874; font-weight: bold;">source</span></span> mysql-server-<span style="color: #000000;">5.1</span>
$ <span style="color: #7a0874; font-weight: bold;">cd</span> mysql-dfsg-<span style="color: #000000;">5.1</span>-5.1.37<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

<p>Nun kopieren wir die Dateien für die Storage-Engine in das entsprechende Verzeichnis:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-R</span> ..<span style="color: #000000; font-weight: bold;">/</span>sphinx-0.9.9<span style="color: #000000; font-weight: bold;">/</span>mysqlse storage<span style="color: #000000; font-weight: bold;">/</span>sphinx</pre></td></tr></table></div>

<p><code>./configure</code> beschwert sich wegen eines fehlenden <code>Docs/</code>-Ordners. Also schnell das Archiv von der MySQL-Seite holen und den entsprechenden Ordner ins Installationsverzeichnis kopieren:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>downloads.mysql.com<span style="color: #000000; font-weight: bold;">/</span>archives<span style="color: #000000; font-weight: bold;">/</span>mysql-<span style="color: #000000;">5.1</span><span style="color: #000000; font-weight: bold;">/</span>mysql-5.1.37.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> temp
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xzvf</span> mysql-5.1.37.tar.gz <span style="color: #660033;">-C</span> temp
$ <span style="color: #c20cb9; font-weight: bold;">mv</span> temp<span style="color: #000000; font-weight: bold;">/</span>mysql-5.1.37<span style="color: #000000; font-weight: bold;">/</span>Docs .
$ <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> temp
$ <span style="color: #c20cb9; font-weight: bold;">rm</span> mysql-5.1.37.tar.gz</pre></td></tr></table></div>

<p>Nun gehts ans Bauen. Die <code>configure</code>-Flags kommen aus <code>debian/rules</code> und sollten denen entprechen, mit denen die Original-Installation von MySQL gebaut wurde:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ BUILD<span style="color: #000000; font-weight: bold;">/</span>autorun.sh
$ .<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>usr \
              <span style="color: #660033;">--exec-prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>usr \
              <span style="color: #660033;">--libexecdir</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>sbin \
              <span style="color: #660033;">--datadir</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share \
              <span style="color: #660033;">--localstatedir</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mysql \
              <span style="color: #660033;">--includedir</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>include \
              <span style="color: #660033;">--infodir</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>info \
              <span style="color: #660033;">--mandir</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">man</span> \
              <span style="color: #660033;">--enable-thread-safe-client</span> \
              <span style="color: #660033;">--enable-local-infile</span> \
              <span style="color: #660033;">--with-pstack</span> \
              <span style="color: #660033;">--with-fast-mutexes</span> \
              <span style="color: #660033;">--with-big-tables</span> \
              <span style="color: #660033;">--with-unix-socket-path</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>mysqld<span style="color: #000000; font-weight: bold;">/</span>mysqld.sock \
              <span style="color: #660033;">--with-mysqld-user</span>=mysql \
              <span style="color: #660033;">--with-libwrap</span> \
              <span style="color: #660033;">--with-ssl</span> \
              <span style="color: #660033;">--without-docs</span> \
              <span style="color: #660033;">--with-extra-charsets</span>=all \
              <span style="color: #660033;">--with-embedded-server</span> \
              <span style="color: #660033;">--with-embedded-privilege-control</span>
$ <span style="color: #c20cb9; font-weight: bold;">make</span></pre></td></tr></table></div>

<p>Danach finden wir im Verzeichnis <code>storage/sphinx/.libs</code> die ladbaren .so-Dateien für MySQL. Diese speichern wir nun in <code>/usr/lib/mysql/plugin</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">/</span>plugin
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">cp</span> storage<span style="color: #000000; font-weight: bold;">/</span>sphinx<span style="color: #000000; font-weight: bold;">/</span>.libs<span style="color: #000000; font-weight: bold;">/</span>ha_sphinx.so<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">/</span>plugin<span style="color: #000000; font-weight: bold;">/</span>
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> mysql:mysql <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">/</span>plugin</pre></td></tr></table></div>

<p>Den Ort müssen wir nun noch MySQL mitteilen. Wir editieren <code>/etc/mysql/my.cnf</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">vi</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">/</span>my.cnf</pre></td></tr></table></div>

<p>Im Abschnitt <code>[mysqld]</code> fügen wir folgende Zeile ein:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">plugin_dir = /usr/lib/mysql/plugin</pre></td></tr></table></div>

<p>Ubuntu nutzt <a href="http://de.wikipedia.org/wiki/AppArmor">AppArmor</a> um zu regeln, welche Programme ausgeführt bzw. geladen werden dürfen. Also müssen wir AppArmor über den neuen Plugin-Ordner informieren:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">vi</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apparmor.d<span style="color: #000000; font-weight: bold;">/</span>usr.sbin.mysqld</pre></td></tr></table></div>

<p>Wir fügen folgende Zeile hinzu:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">/usr/lib/mysql/plugin/* mr,</pre></td></tr></table></div>

<p>Danach AppArmor und MySQL neu starten:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <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>apparmor restart
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <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>mysql restart</pre></td></tr></table></div>

<p>Zu guter Letzt installieren wir das Plugin:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ mysql <span style="color: #660033;">-u</span> root <span style="color: #660033;">-p</span>
mysql<span style="color: #000000; font-weight: bold;">&gt;</span> INSTALL PLUGIN sphinx SONAME <span style="color: #ff0000;">'ha_sphinx.so'</span>;
Query OK, <span style="color: #000000;">0</span> rows affected <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0.00</span> sec<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>Danach sollte Sphinx als Engine auftauchen und die &#8220;Support&#8221;-Spalte sollte &#8220;YES&#8221; enthalten:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">mysql&gt; show engines;
+------------+----------+---------------------------------------------------------+
| Engine     | Support  | Comment                                                 |
+------------+----------+---------------------------------------------------------+
| MyISAM     | DEFAULT  | Default engine as of MySQL 3.23 with great performance  |
  ...
| SPHINX     | YES      | Sphinx storage engine 0.9.9                             |
  ...
+------------+----------+---------------------------------------------------------+
13 rows in set (0.00 sec)</pre></td></tr></table></div>

<h3>Links zum Thema</h3>
<ul>
<li><a href="http://www.sphinxsearch.com">Sphinx</a></li>
<li><a href="http://www.sphinxsearch.com/docs/current.html#sphinxse">SphinxSE Dokumentation</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html">MySQL Fulltext-Index</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=Sphinx+und+SphinxSE+unter+Ubuntu+installieren+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D168+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/&amp;title=Sphinx+und+SphinxSE+unter+Ubuntu+installieren" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/&amp;title=Sphinx+und+SphinxSE+unter+Ubuntu+installieren" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/&amp;t=Sphinx+und+SphinxSE+unter+Ubuntu+installieren" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/&amp;title=Sphinx+und+SphinxSE+unter+Ubuntu+installieren" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/JPh5YSXKVUE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<series:name><![CDATA[Schöner suchen mit Sphinx]]></series:name>
	<feedburner:origLink>http://sorgalla.com/2009/12/15/sphinx-und-sphinxse-unter-ubuntu-installieren/</feedburner:origLink></item>
		<item>
		<title>HTMLPurifier mit dem Zend Framework nutzen, Teil 2</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/O_ibTYpGg30/</link>
		<comments>http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 19:33:33 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[HTMLPurifier]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[Zend_View_Helper]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=179</guid>
		<description><![CDATA[Im ersten Teil haben wir uns mit der Installation und Integration von HTMLPurifier als Filter für Eingaben beschäftigt. Diesmal geht es um darum Ausgaben entsprechend zu filtern, getreu dem Motto &#8220;Filter input, Escape output&#8221;. Erstellung eines View Helpers Um Variablen in View-Skripten zu escapen, bietet sich ein View Helper an. Wir erstellen uns den Helper [...]]]></description>
				<content:encoded><![CDATA[<p>Im <a href="/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/">ersten Teil</a> haben wir uns mit der Installation und Integration von HTMLPurifier als Filter für Eingaben beschäftigt. Diesmal geht es um darum Ausgaben entsprechend zu filtern, getreu dem Motto &#8220;Filter input, Escape output&#8221;.<span id="more-179"></span></p>
<h3>Erstellung eines View Helpers</h3>
<p>Um Variablen in View-Skripten zu escapen, bietet sich ein <a href="http://framework.zend.com/manual/en/zend.view.helpers.html">View Helper</a> an.</p>
<p>Wir erstellen uns den Helper in <code>library/App/View/Helper/HtmlPurifier.php</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>?php
<span style="color: #009933; font-style: italic;">/**
 * @see Zend_View_Helper_Abstract
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/View/Helper/Abstract.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @see App_Filter_HtmlPurifier
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'App/Filter/HtmlPurifier.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @category App
 * @package App_View
 * @subpackage Helper
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Zend_View_Helper_HtmlPurifier <span style="color: #000000; font-weight: bold;">extends</span> Zend_View_Helper_Abstract
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Returns the string $value, purified by HTMLPurifier
     *
     * @param string $value
     * @param mixed $config
     * @return string
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> htmlPurifier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$filter</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> App_Filter_HtmlPurifier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$filter</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Der Code ist relativ simpel, da wir einfach unseren bereits erstellten Filter nutzen.</p>
<p>Nun müssen wir dem <code>Zend_View</code>-Objekt den <a href="http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.paths">Helper-Pfad</a> mitteilen:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHelperPath</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'App/View/Helper'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'App_View_Helper'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Oder alternativ, falls <a href="http://framework.zend.com/manual/en/zend.application.available-resources.html#zend.application.available-resources.view">Zend_Application</a> genutzt wird, folgendes in die application.ini eintragen:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">resources.view.helperPath.app.App_View_Helper = &quot;App/View/Helper&quot;</pre></td></tr></table></div>

<p>Und so lässt sich dann der View Helper in den View-Skripten nutzen:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&lt;p&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">htmlPurifier</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment_text</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTML.Allowed'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'b,strong,a[href]'</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>
&lt;/p&gt;</pre></td></tr></table></div>

<h3>Links zum Thema</h3>
<ul>
<li><a href="http://htmlpurifier.org">HTMLPurifier</a></li>
<li><a href="http://framework.zend.com/manual/en/zend.view.helpers.html">Zend_View-Helpers</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=HTMLPurifier+mit+dem+Zend+Framework+nutzen%2C+Teil+2+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D179+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen%2C+Teil+2" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen%2C+Teil+2" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/&amp;t=HTMLPurifier+mit+dem+Zend+Framework+nutzen%2C+Teil+2" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen%2C+Teil+2" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/O_ibTYpGg30" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[HTMLPurifier mit dem Zend Framework nutzen]]></series:name>
	<feedburner:origLink>http://sorgalla.com/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/</feedburner:origLink></item>
		<item>
		<title>HTMLPurifier mit dem Zend Framework nutzen</title>
		<link>http://feedproxy.google.com/~r/sorgalla/~3/pXxf0aeSc7o/</link>
		<comments>http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 14:50:24 +0000</pubDate>
		<dc:creator>jan</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[HTMLPurifier]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[Zend_Filter]]></category>

		<guid isPermaLink="false">http://sorgalla.com/?p=93</guid>
		<description><![CDATA[Pádraic Brady hat in seinem Blog über Zend_Filter_StripTags und seine mögliche missbräuchliche Verwendung als XSS-Filter geschrieben und damit einiges an Aufsehen erregt. Ich selbst bin zufällig kürzlich über die Klasse gestolpert. Ohne sie groß zu testen war mir der Code aber relativ suspekt und ich habe sie nicht verwendet. Stattdessen nutze ich wie bisher HTMLPurifier [...]]]></description>
				<content:encoded><![CDATA[<p>Pádraic Brady hat in seinem <a href="http://blog.astrumfutura.com/archives/425-Zend_Filter_StripTags-Friend,-Foe,-or-Security-Nightmare.html">Blog über Zend_Filter_StripTags</a> und seine mögliche missbräuchliche Verwendung als XSS-Filter geschrieben und damit einiges an Aufsehen erregt. Ich selbst bin zufällig kürzlich über die Klasse gestolpert. Ohne sie groß zu testen war mir der Code aber relativ suspekt und ich habe sie nicht verwendet.</p>
<p>Stattdessen nutze ich wie bisher <a href="http://htmlpurifier.org">HTMLPurifier</a> (wird übrigens auch von Pádraic in seinem Artikel empfohlen).</p>
<blockquote><p>HTML Purifier is a standards-compliant HTML filter library written in PHP. HTML Purifier will not only remove all malicious code (better known as XSS) with a thoroughly audited, secure yet permissive whitelist, it will also make sure your documents are standards compliant, something only achievable with a comprehensive knowledge of W3C&#8217;s specifications. Tired of using BBCode due to the current landscape of deficient or insecure HTML filters? Have a WYSIWYG editor but never been able to use it? Looking for high-quality, standards-compliant, open-source components for that application you&#8217;re building? HTML Purifier is for you!</p></blockquote>
<p>Glücklicherweise lässt sich HTMLPurifier sehr leicht in das Zend Framework integrieren.<br />
<span id="more-93"></span></p>
<h3>Installation von HTMLPurifier</h3>
<p>Am einfachsten lässt sich HTMLPurifier über PEAR installieren:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ pear channel-discover htmlpurifier.org
$ pear <span style="color: #c20cb9; font-weight: bold;">install</span> hp<span style="color: #000000; font-weight: bold;">/</span>HTMLPurifier</pre></td></tr></table></div>

<p>Alternativ kann man sich die Bibliothek auch <a href="http://htmlpurifier.org/download">herunterladen</a> und im <code>library</code>-Ordner (Parallen zum <code>Zend</code>-Ordner) installieren.</p>
<h3>Filtern mit HTMLPurifier</h3>
<p>Um HTMLPurifier in Zend Framework-Projekten nutzen zu können, erstellen wir uns einen Filter der <code>Zend_Filter_Interface</code> implementiert.</p>
<p>Wir erstellen uns den Filter in <code>library/App/Filter/HtmlPurifier.php</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * @see Zend_Filter_Interface
 */</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Filter/Interface.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @category App
 * @package App_Filter
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> App_Filter_HtmlPurifier implements Zend_Filter_Interface
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * The HTMLPurifier instance
     *
     * @var HTMLPurifier
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_instance</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Constructor
     *
     * @param mixed $config
     * @return void
     */</span>
    <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;">$config</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</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: #339933;">!</span><span style="color: #990000;">class_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTMLPurifier_Bootstrap'</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;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'HTMLPurifier/Bootstrap.php'</span><span style="color: #339933;">;</span>
            <span style="color: #990000;">spl_autoload_register</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTMLPurifier_Bootstrap'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'autoload'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_instance <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HTMLPurifier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Defined by Zend_Filter_Interface
     *
     * Returns the string $value, purified by HTMLPurifier
     *
     * @param string $value
     * @return string
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> filter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</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>_instance<span style="color: #339933;">-&gt;</span><span style="color: #004000;">purify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Die einfachste Variante um HTML zu filtern ist nun:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$filter</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> App_Filter_HtmlPurifier<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cleanHtml</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$filter</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dirtyHtml</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Die Variable <code>$config</code>, die wir dem Konstruktor übergeben, kann dabei ein <code>HTMLPurifier_Config</code>-Objekt, ein Array oder der Pfad zu einer .ini-Datei sein. Mehr Informationen dazu findet man in der <a href="http://htmlpurifier.org/live/INSTALL">INSTALL-Datei </a>von HTMLPurifier.</p>
<p>Warum aber HTMLPurifier in einem Filter verstecken? Wir könnten doch auch direkt das HTMLPurifier-Objekt nutzen? Der Vorteil ist, dass wir so den Filter in andere Komponenten des Zend Frameworks integrieren können.</p>
<p>Als erstes kommt uns da natürlich Zend_Form in den Sinn. Man kann so den Filter für seine Formular-Elemente nutzen, z. B. für Textfelder in die HTML-Code eingetragen werden kann um den Markup valide zu machen oder um nur bestimmte Tags zu erlauben.</p>
<p>Als Beispiel hier ein Kommentar-Textfeld in dem nur <code>&lt;b></code>,  <code>&lt;strong></code> und  <code>&lt;a></code>-Tags erlaubt sind. Bei den  <code>&lt;b></code> und  <code>&lt;strong></code>-Tags sind keine Attribute erlaubt, beim  <code>&lt;a></code>-Tag nur das  <code>href</code>-Attribut.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElementPrefixPath</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'App_Filter'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'App/Filter'</span><span style="color: #339933;">,</span> Zend_Form_Element<span style="color: #339933;">::</span><span style="color: #004000;">FILTER</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addElement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'textarea'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment_text'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Kommentar'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'filters'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HtmlPurifier'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HTML.Allowed'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'b,strong,a[href]'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>HTMLPurifier akzeptiert eine Vielzahl von Konfigurations-Optionen. Ein Blick in die <a href="http://htmlpurifier.org/live/configdoc/plain.html">Dokumentation</a> hilft.</p>
<p>Somit haben wir den ersten Teil von &#8220;Filter input, Escape output&#8221; erledigt. Im <a href="/2009/12/12/htmlpurifier-mit-dem-zend-framework-nutzen-teil-2/">2. Teil</a> werden wir dann einen Blick auf die Implementierung eines Zend_View_Helpers werfen mit dem wir Variablen in View-Skripten entsprechend filtern können.</p>
<h3>Links zum Thema</h3>
<ul>
<li><a href="http://htmlpurifier.org">HTMLPurifier</a></li>
<li><a href="http://framework.zend.com/manual/en/zend.filter.html">Zend_Filter</a></li>
<li><a href="http://framework.zend.com/manual/en/zend.form.elements.html#zend.form.elements.filters">Zend_Form Filter</a></li>
</ul>
<div class="tweetthis" style="text-align:left;"><p> <a target="_blank" class="tt" href="http://twitter.com/intent/tweet?text=HTMLPurifier+mit+dem+Zend+Framework+nutzen+http%3A%2F%2Fsorgalla.com%2F%3Fp%3D93+%2Fby+%40jansor" title="Post to Twitter"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/twitter/tt-twitter3.png" alt="Post to Twitter" /></a> <a target="_blank" class="tt" href="http://delicious.com/post?url=http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen" title="Post to Delicious"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/delicious/tt-delicious.png" alt="Post to Delicious" /></a> <a target="_blank" class="tt" href="http://digg.com/submit?url=http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen" title="Post to Digg"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/digg/tt-digg.png" alt="Post to Digg" /></a> <a target="_blank" class="tt" href="http://www.facebook.com/share.php?u=http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/&amp;t=HTMLPurifier+mit+dem+Zend+Framework+nutzen" title="Post to Facebook"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/facebook/tt-facebook.png" alt="Post to Facebook" /></a> <a target="_blank" class="tt" href="http://reddit.com/submit?url=http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/&amp;title=HTMLPurifier+mit+dem+Zend+Framework+nutzen" title="Post to Reddit"><img class="nothumb" src="http://sorgalla.com/wp-content/plugins/tweet-this/icons/en/reddit/tt-reddit.png" alt="Post to Reddit" /></a></p></div><img src="http://feeds.feedburner.com/~r/sorgalla/~4/pXxf0aeSc7o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[HTMLPurifier mit dem Zend Framework nutzen]]></series:name>
	<feedburner:origLink>http://sorgalla.com/2009/12/09/htmlpurifier-mit-dem-zend-framework-nutzen/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 9.331 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-04-22 11:04:01 -->
