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

<channel>
	<title>iTopiaBlog &#187; PHP</title>
	<atom:link href="http://blog.itopia.de/category/programmierung/php/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.itopia.de</link>
	<description>liVe iN oRder tO lEArN</description>
	<lastBuildDate>Thu, 26 Jan 2012 16:41:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Windows Azure: Custom PHP installation</title>
		<link>http://blog.itopia.de/windows-azure-custom-php-installation/366</link>
		<comments>http://blog.itopia.de/windows-azure-custom-php-installation/366#comments</comments>
		<pubDate>Wed, 25 Jan 2012 10:02:43 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=366</guid>
		<description><![CDATA[I write this article because of an odyssey of bug tracing concerning my PHP application hosted in the Windows Azure<a href="http://blog.itopia.de/windows-azure-custom-php-installation/366" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>I write this article because of an odyssey of bug tracing concerning my PHP application hosted in the Windows Azure cloud.</p>
<p>Before the <a href="http://www.microsoft.com/web/gallery/install.aspx?appid=WindowsAzureToolsVS2010">Windows Azure SDK 1.6</a> the configuration of PHP with Fast CGI was done in the <em>Web.config</em>. Here you could define the exact path of your custom PHP.</p>
<p>Now with the SDK 1.6 and the different folder structure defined by the scaffolder, the integration of PHP has changed. The new way is to install PHP automatically by the predefined startup scripts. So you don&#8217;t need to put the whole PHP stuff into your package. You just add your <em>php.ini</em> modifications and maybe your special PHP extension DLLs.</p>
<p>Now, when you deploy your package the startup scripts will add some environment variables,  install PHP53, SQLDriverPHP53IIS and PHPManager.</p>
<p>That&#8217;s all quite cool, but last week my live application crashed (WORST CASE!) without any modifications by my side. I could not find the problem. A few days ago I recognized that on the compute instances runs a different PHP version than on my local dev environment. I could not figure out how this could happen. But since I know that the startup script uses <strong>webpicmdline </strong>(Web Plattform Installer for Commandline) to <a href="http://msdn.microsoft.com/en-us/library/windowsazure/hh691735%28v=vs.103%29.aspx">install the PHP</a> stuff (s.o.) it&#8217;s clear to me. The WebPI always takes the newest PHP version for installation, and it&#8217;s not possible to set up a specific version number. In my case in need PHP 5.3.8 but WebPI installs PHP 5.3.9 which crashes my application with an ugly PHP53_via_FastCGI  Error Code 0xc0000005.</p>
<p>Ok, how can I tell Azure to take my PHP version. The only way is to again put the whole PHP folder into the deployment package as explained in this <a href="http://azurephp.interoperabilitybridges.com/articles/using-a-custom-php-installation">tutorial</a>.</p>
<p>I for my use case I needed to do it a little bit different:</p>
<ul>
<li>I put the PHP folder into <em>MyProject\WebRole\bin\PHP\v5.3\php-cgi.exe</em></li>
<li>The extensions are in <em>MyProject\WebRole\bin\PHP\v5.3\ext\</em></li>
<li>In <em>configureIIS.cmd</em> I changed <code>SET PHP_FULL_PATH=%~dp0php\php-cgi.exe </code>to<code> </code><code>SET PHP_FULL_PATH=%~dp0<strong>PHP\v5.3</strong>\php-cgi.exe</code></li>
<li>To add the environment variables I leave <em>add-environment-variables.cmd</em> as it was</li>
<li>To set user permission I leave <em>monitor-environment.cmd</em> as it was</li>
</ul>
<p>These changes bring some small losings (with which I can live):</p>
<ul>
<li>SQLDriverPHP53IIS needs to be installed manually (<a href="http://msdn.microsoft.com/de-de/library/cc296170%28v=sql.90%29.aspx">ext\php_sqlsrv_53_nts_vc9.dll</a> [<a href="http://dll-files.org/10808/php_sqlsrv_53_nts_vc9.dll.html">2</a>]).</li>
<li>No IIS PHPManager (Maybe it&#8217;s possible to install it by modifing the<em> install-php.cmd</em>).</li>
</ul>
<p>The startup script part in my <em>ServiceDefinition.csdef</em> now looks like:</p>
<pre class="brush:xml">    &lt;Startup&gt;
      &lt;Task commandLine="add-environment-variables.cmd" executionContext="elevated" taskType="simple" /&gt;
      &lt;Task commandLine="installCustomPHP.cmd" executionContext="elevated" taskType="simple"&gt;
        &lt;Environment&gt;
          &lt;Variable name="EMULATED"&gt;
            &lt;RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" /&gt;
          &lt;/Variable&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine="monitor-environment.cmd" executionContext="elevated" taskType="background" /&gt;
    &lt;/Startup&gt;</pre>
<p>I renamed the <em>configureIIS.cmd</em> from the tutorial to <em>installCustomPHP.cmd</em>.</p>
<p><strong>One thing</strong>: It very strange to make the experience as Azure PHP developer that there are sometime changes within the Azure Plattform which are crashing my live application. And I have no chance to get warned/informed early enough to fix the problems before my customers get a blank page.</p>
<p>Corrections, tips and hints are welcome <img src='http://blog.itopia.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Links:</strong></p>
<ul>
<li><a href="http://www.microsoft.com/web/gallery/install.aspx?appid=WindowsAzureToolsVS2010">Windows Azure SDK 1.6</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/windowsazure/hh691735%28v=vs.103%29.aspx">How to use WebPI to install PHP</a></li>
<li><a href="http://azurephp.interoperabilitybridges.com/articles/using-a-custom-php-installation">Using a custom PHP installation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/windows-azure-custom-php-installation/366/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Azure SDK 1.6 Update &amp; Windows Azure for PHP</title>
		<link>http://blog.itopia.de/windows-azure-sdk-1-6-update-php/348</link>
		<comments>http://blog.itopia.de/windows-azure-sdk-1-6-update-php/348#comments</comments>
		<pubDate>Fri, 02 Dec 2011 11:38:44 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[Could Computing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Windows Azure for PHP]]></category>
		<category><![CDATA[Windows Azure SDK 1.6]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=348</guid>
		<description><![CDATA[Windows Azure came up with a new SDK update &#8220;Windows Azure SDK 1.6&#8243;. In our case it brought a lot<a href="http://blog.itopia.de/windows-azure-sdk-1-6-update-php/348" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Windows Azure came up with a new SDK update &#8220;Windows Azure SDK 1.6&#8243;.</p>
<p>In our case it brought a lot of hair tearing chances with it. Because so far we developed our PHP application with eclispe and the out-dated  <a href="http://www.windowsazure4e.org/">windowsazue4e</a> Plugin.</p>
<p>Eclipse presetting for the folder structure was like this:</p>
<pre class="brush:plain">C:\WindowsAzurePHPApp
|_ ServiceDefinition.csdef
|_ ServiceConfiguraion.cscfg
|_ ServiceDefinition.csx (Development approot folder)
|_ WindowsAzurePHPApp.cspkg (Package file)

C:\WindowsAzurePHPApp_WebRole
|_ php
|_ Web.config
|_ Web.roleconfig
|_ index.php</pre>
<p>Whereas the new <a href="http://azurephp.interoperabilitybridges.com/articles/build-and-deploy-a-windows-azure-php-application#h2Section4">scaffolding</a> advices the following structure:</p>
<pre class="brush:plain">C:\WindowsAzurePHPApp
|_ ServiceDefinition.csdef
|_ ServiceConfiguraion.cscfg
|_ WebRole
|_ build
|    |_ [Local dev. package files]
|_ pack [Package files]
|    |_ WindowsAzurePHPApp.cspkg
|    |_ ServiceConfiguraion.cscfg
|_ php
|    |_ [The whole PHP libs]
|_ bin
|    |_ [Start up scripts]
|_ index.php</pre>
<p>Command to run the development build:</p>
<pre class="brush:shell">package create -in="C:\temp\WindowsAzurePHPApp"
   -out="C:\temp\WindowsAzurePHPApp\build" -dev=true</pre>
<p>Command to generate the cloud package:</p>
<pre class="brush:shell">package create -in="C:\temp\WindowsAzurePHPApp"
   -out="C:\temp\WindowsAzurePHPApp\pack" -dev=false</pre>
<p>&nbsp;</p>
<p><strong>Preparing everything:</strong></p>
<ol>
<li><a href="http://www.microsoft.com/windowsazure/sdk">Get the Windows Azure SDK<br />
</a>The best way is it to use the Windows Web Platform Installer. Follow step by step the instructions <a href="http://azurephp.interoperabilitybridges.com/articles/setup-the-windows-azure-development-environment-automatically-with-the-microsoft-web-platform-installer">here</a>.<a href="http://www.microsoft.com/windowsazure/sdk"></a></li>
<li>Get the new <a href="http://phpazure.codeplex.com/">WindowsAzure for PHP SDK</a>.<br />
Set it up step by step using the instructions <a href="http://azurephp.interoperabilitybridges.com/articles/setup-the-windows-azure-sdk-for-php">here</a>.<br />
If you use classes from this SDK within your project you should also put a copy into your project itself.</li>
</ol>
<p><strong>What to change after the SDK update:</strong></p>
<ol>
<li><strong>Generate a sample project:</strong><br />
To have a clean sample project for copying the needed parts to the our project we generate it by using the new scaffoldig functionality of the <a href="http://phpazure.codeplex.com/">WindowsAzure for PHP SDK</a>:<br />
Open the command line and run:&nbsp;</p>
<pre class="brush:shell">scaffolder run -out="C:\temp\WindowsAzurePHPApp"</pre>
<p>Now we have clean and simple sample project.<br />
Test everything by following these <a href="http://azurephp.interoperabilitybridges.com/articles/build-and-deploy-a-windows-azure-php-application#h2Section4">steps</a>.</p>
<p><strong> </strong></li>
<li><strong>Move the sources into the new folder structure:<br />
</strong>Rebuild the sample structure for our project and move your files into it.<strong> </strong>&nbsp;</p>
<ul>
<li>Replace the <em>php-folder</em> with the php folder in c:\program files\PHP\v5.3 (installed with the Web Platform Installer) and edit the <em>php.in</em>i with your settings.<br />
Set the xtension directory to:&nbsp;</p>
<pre class="brush:plain">extension_dir="ext"</pre>
</li>
<li>Replace the old <em>bin-folder</em> with the bin folder of the sample project.</li>
<li>Edit the PHP-paths within cmd-scripts in the <em>bin-folder</em>.</li>
</ul>
<p><strong> </strong></li>
<li><strong>ServiceDefinition.csdef configuration: </strong>
<ul>
<li>Add the <a href="http://msdn.microsoft.com/en-us/library/gg557553.aspx#Sites">Sites-Element</a>.</li>
<li>Add the Startup-Element for the PHP installation.</li>
</ul>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;ServiceDefinition name="WindowsAzurePHPApp" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"&gt;
  &lt;WebRole enableNativeCodeExecution="true" name="WebRole" vmsize="ExtraSmall"&gt;
    &lt;Sites&gt;
      &lt;Site name="Web" physicalDirectory="./WebRole"&gt;
        &lt;Bindings&gt;
          &lt;Binding name="HttpIn" endpointName="HttpIn" /&gt;
        &lt;/Bindings&gt;
      &lt;/Site&gt;
    &lt;/Sites&gt;
    &lt;Startup&gt;
      &lt;Task commandLine="add-environment-variables.cmd" executionContext="elevated" taskType="simple" /&gt;
      &lt;Task commandLine="install-php.cmd" executionContext="elevated" taskType="simple"&gt;
        &lt;Environment&gt;
          &lt;Variable name="EMULATED"&gt;
            &lt;RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" /&gt;
          &lt;/Variable&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine="monitor-environment.cmd" executionContext="elevated" taskType="background" /&gt;
    &lt;/Startup&gt;
    &lt;InputEndpoints&gt;
      &lt;InputEndpoint name="HttpIn" port="80" protocol="http"/&gt;
    &lt;/InputEndpoints&gt;
    &lt;ConfigurationSettings&gt;
      ...
    &lt;/ConfigurationSettings&gt;
  &lt;/WebRole&gt;
&lt;/ServiceDefinition&gt;</pre>
</li>
<li><strong>ServiceConfiguraion.cscfg configuration:</strong><br />
Add the <em>osFamily </em>and <em>osVersion </em>attributes:&nbsp;</p>
<pre class="brush:xml">&lt;ServiceConfiguration serviceName="Stats" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*"&gt;
...
&lt;/ServiceConfiguration&gt;</pre>
</li>
<li><strong>Web.config configuration:</strong>
<ul>
<li>Remove the Handlers-Element for PHP via FastCGI (By now on this will be handled by the startup scripts)</li>
</ul>
</li>
</ol>
<p>&nbsp;</p>
<p><strong>Important changes with the new SDK:</strong></p>
<ul>
<li>$_SERVER['RoleRoot'] doesn&#8217;t exist anymore.</li>
<li>$_SERVER['INSTANCE_ID']  doesn&#8217;t contain a local Instance number like &#8220;1&#8243; or &#8220;2&#8243; anymore. It seams that  it&#8217;s now a global number like &#8220;16325987&#8243;.<br />
Alternativly you can use [RoleInstanceID] =&gt; WebRole_IN_0.</li>
<li>$_SERVER['TEMP'] is not the same drive like the accessable <a href="http://msdn.microsoft.com/en-us/library/gg557553.aspx#LocalStorage">local storage</a> any more, so you can&#8217;t use it to locate the current letter of the accessable this drive. I don&#8217;t know if it&#8217;s always &#8220;<strong>c:\</strong>&#8220;.</li>
<li>The PHP method <strong>azure_getconfig(&#8216;StorageAccountName&#8217;)</strong> does not exist anymore. This method could be used to get the setting values of the ServiceConfiguration.cscnf.<br />
Even if I copy the php_azure.dll of the old project into the new one and enabling the extension (extension=php_azure.dll) in th ephp.ini, it does not work.</li>
<li>The file Web.roleconfig is deprecated.</li>
</ul>
<p><strong> </strong></p>
<p>&nbsp;</p>
<p><strong>Links:</strong></p>
<ul>
<li><a href="http://www.microsoft.com/windowsazure/sdk">Windows Azure SDK for PHP</a></li>
<li><a href="http://azurephp.interoperabilitybridges.com/articles/setup-the-windows-azure-sdk-for-php">Setup the Windows Azure SDK for PHP</a></li>
<li><a href="http://azurephp.interoperabilitybridges.com/articles/build-and-deploy-a-windows-azure-php-application">Build and deploy a Windows Azure PHP application</a></li>
<li><a href="http://azurephp.interoperabilitybridges.com/articles/setup-the-windows-azure-development-environment-automatically-with-the-microsoft-web-platform-installer">Setup the Windows Azure Development Environment automatically with the Microsoft Web Platform Installer</a></li>
<li><a href="http://phpazure.codeplex.com/discussions/281065">Windows Azure SDK 1.6 Update PHP Discussion</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/gg557553.aspx">ServiceDefinition Schema</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee758710.aspx">Service Configuration Schema</a></li>
<li><a href="http://blogs.msdn.com/b/silverlining/archive/2011/11/23/packaging-a-custom-php-installation-for-windows-azure.aspx">Packaging a Custom PHP Installation for Windows Azure</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/windows-azure-sdk-1-6-update-php/348/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Symfony 1.4: Doctrine: There is no open connection</title>
		<link>http://blog.itopia.de/symfony-1-4-doctrine-there-is-no-open-connection/342</link>
		<comments>http://blog.itopia.de/symfony-1-4-doctrine-there-is-no-open-connection/342#comments</comments>
		<pubDate>Wed, 31 Aug 2011 15:04:25 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Connection]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=342</guid>
		<description><![CDATA[When you have this problem just go into your controler e.g. index.php and add the following line: $configuration = ProjectConfiguration::getApplicationConfiguration('frontend',<a href="http://blog.itopia.de/symfony-1-4-doctrine-there-is-no-open-connection/342" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>When you have this problem just go into your controler e.g. index.php and add the following line:</p>
<pre><code>
<pre class="brush:php">$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'test', true);
new sfDatabaseManager($configuration);
</pre>
<p></code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/symfony-1-4-doctrine-there-is-no-open-connection/342/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Symfony Framework Pros&amp;Contras</title>
		<link>http://blog.itopia.de/php-symfony-framework-pros-contras-zen/298</link>
		<comments>http://blog.itopia.de/php-symfony-framework-pros-contras-zen/298#comments</comments>
		<pubDate>Mon, 14 Feb 2011 21:28:34 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=298</guid>
		<description><![CDATA[Im Folgenden werden u.a. die Pros und Contras des Symfony-Frameworks vorgestellt, welches für viele als eine mögliche Alternative zur aktuellen<a href="http://blog.itopia.de/php-symfony-framework-pros-contras-zen/298" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Im Folgenden werden u.a. die Pros und Contras des Symfony-Frameworks vorgestellt, welches für viele als eine mögliche Alternative zur aktuellen Lösung angesehen wird.</p>
<h2>Definition</h2>
<p>Das Symfony-Framework wurde von Sensio Labs entwickelt. Es kapselt jahrelange Erfahrung der PHP-Entwicklung und vereinfacht enorm die Entwicklung mittlerer bis großer Web-Projekte. Es ist aus der Idee heraus entstanden das perfekte Tool für Web-Entwickler zu kreieren die Kunden mit hoch performanten Ansprüchen bedienen.</p>
<p>Symfony basiert auf dem MVC Design-Pattern und versucht die Entwickler selbst dazu zu bringen sauberen, gut strukturierten Code zu produzieren. D.h. in Templates nur Präsentationslogik, Controller lediglich als eine Art schlankes Batch-Script zu gebrauchen und die Businesslogik in den Modell- und Form-Klassen zu hinterlegen.</p>
<p>Es bietet zahlreiche Hilfsmittel um die Entwicklungszeit von komplexen Web-Applikationen stark zu reduzieren. Außerdem sind gängige Aufgaben automatisiert, so dass sich die Entwickler mehr auf die Anwendungslogik konzentrieren können. Ziel ist es das Rad nicht immer wieder neu zu erfinden wenn eine neue Web-Applikation entwickelt wird.</p>
<p>Symfony ist komplett in PHP geschrieben und hat sich bereits in zahlreichen Real-World-Projekten bewiesen. Darunter auch High-Demand Webseiten (z.B. delicious.com und answers.yahoo.com, dailymotion.com).</p>
<h2>Symfony Features</h2>
<p>Symfony wurde entwickelt um die folgenden Anforderungen zu erfüllen:</p>
<ul>
<li>Einfach auf den 	gängigsten Plattformen zu installieren und konfigurieren.</li>
<li>Datenbank-Engine-Unabhängig.</li>
<li>Ãœberwiegend einfach 	zu benutzen aber dennoch flexibel genug um komplexe Klassen zu 	adaptieren.</li>
<li>Verträglich mit den 	meisten Web-Best-Practises.</li>
<li>Stabil genug für 	Langzeit-Projekte.</li>
<li>Sehr lesbarer Code 	mit phpDocumenter-Kommentaren für einfache Wartung.</li>
<li>Einfach zu erweitern. 	Integration von anderen Code-Bibliotheken ist möglich.</li>
<li>Ein Mal geschriebener 	Code soll möglichst einfach wiederverwendbar sein (Components, 	Slots).</li>
</ul>
<h3>Webprojekt-Features</h3>
<ul>
<li>Symfony Autoloader 	für .class.php Dateien in lib-Verzeichnissen.</li>
<li>Parameter-Holder für 	saubere Ãœbergabe von http-Request Parametern mit Getter und Setter.</li>
<li>Internationalisierungs-Ebene.</li>
<li>Die 	Präsentations-Ebene ist Template-basiert und unterstützt 	AJAX-Funktionalitäten (jQuery).</li>
<li>Formulare lassen sich 	automatisiert validieren und einfach wiederverwenden.</li>
<li>Ausgabefilterung 	schätzt vor Cross-Site-Scripting durch korrupte Daten.</li>
<li>Die 	Cache-Management-Features reduzieren die Bandbreitennutzung und den 	Server-Load.</li>
<li>Authentifizierungs- 	und Rechtefeatures vereinfachen die Erstellung von geschätzten 	Bereichen und ermöglichen Benutzer-Sicherheits-Management.</li>
<li>Routing und Smart 	URLs machen Seitenadressen Suchmaschinen tauglich.</li>
<li>E-Mail-Management 	(SWIFT-Mailer).</li>
<li>Benutzerfreundliche 	Listen durch automatisch generierte Pager, Sortierer und Filter.</li>
<li>Factories, Plugins 	und Events ermöglichen einen hohen Grad der Erweiterbarkeit.</li>
</ul>
<h2>Entwicklungsumgebung und Werkzeuge</h2>
<p>Symfony beinhaltet bereits standardmäßig verschiedene Entwicklungsumgebungen und bietet verschiedene Werkzeuge  und automatisierte Tasks für gängige Aufgaben der Software-Entwicklung:</p>
<ul>
<li>Code-Generierungs-Werkzeuge 	sind bestens geeignet für Prototypen und Administrationen.</li>
<li>Das eingebaute Unit- 	und Functional-Testing Framework bietet Tools für 	Test-Driven-Development-Unterstützung.</li>
<li>Das Debug-Panel 	beschleunigt das Debugging durch das Anzeigen vieler wichtiger 	Seiten-Informationen die ein Entwickler benätigt (SQL Queries, 	Ladezeiten, Chaching-Informationen, http-Parameter, Logs, 	Umgebungsvariablen etc.).</li>
<li>Kommandozeilen-Schnittstellen 	automatisieren das Deployment zwischen zwei Servern.</li>
<li>Live-Änderung an den 	Konfigurationen sind möglich und effektiv.</li>
<li>Die Logging- und 	Exception-Features geben Administratoren Transparenz über die 	Anwendungsaktivitäten.</li>
</ul>
<h2>Symfony vs. Zend</h2>
<p>An dieser Stelle muss zuerst erwÃ¤hnt werden, dass sich beide Frameworks wohl kaum vergleichen lassen, da sie unterschiedlicher nicht sein könnten.</p>
<p>Wie das .NET Framework ist das Zend Framework (ZF) eine Ansammlung von Funktionen welche zusammen gute Schnittstellen bereitstellen um die komplexesten Anforderungen, die regelmäig auftreten, von Webentwicklern zu befriedigen. Der größte Vorteil aber auch Nachteil von ZF ist, dass es keinen bestimmten Weg bzw. Konventionen vorgibt wie die Anforderungen zu bewerkstelligen sind.</p>
<p>Bei ZF gibt es kaum Code-Generierung und Konfigurationen werden alle im Front-Controller vorgenommen. Symfony (SF) generiert anhand des DB-Schemas eine Menge Code, welcher zunächst die Code-Basis aufbläht aber den Entwicklern viel Zeit erspart. Konfigurationen (wie Authentifizierung, Caching, Layout uvm.) können in hierarchischer Erbreihenfolge von Applikation über Module bis hinunter zur einzelnen Action über YAML-Files vorgenommen werden. ZF lässt einem bei der Ordnerstruktur alle Freiheiten, wohingegen symfony eine strikte Struktur vorgibt. Dies trägt am Anfang nicht zu einer höheren Lernkurve bei, aber die Einheitlichkeit lässt die Entwickler später sehr leicht im Code navigieren.</p>
<p>Symfony hat eine sehr gute und aktuelle online Dokumentation sowie daraus entstandene Begleitbücher. Darüber hinaus ist die Community sehr aktiv und auch bei komplexeren Problemen sehr hilfreich. ZF verfügt leider nicht Ã¼ber so viel Dokumentation und richtet sich sehr stark an die erfahreneren Entwickler die schon sehr geübt sind mit den komplexeren Aspekten der objektorientierten Programmierung.</p>
<p>Im Gegensatz zu ZF hat SF eine sehr aktive Plugin- und Erweiterungs-Community. Man kann sogar ZF-Funktionalitäten über das Zend-Framework-Plugin in Symfony integrieren.</p>
<h2>Symfony 1.4 vs Symfony2</h2>
<p>Sensio Labs veröffentlicht ein neues Major-Release Symfony2.0, worauf dieser Abschnitt kurz eingeht:</p>
<p>Unterschiede (soweit bekannt):</p>
<ul>
<li>Neues Template-System 	(Twig), bisher PHP-Files die von den Actions die Template-Variablen 	erben.</li>
<li>Partials und 	Page-Templates werden nicht mehr unterschieden.</li>
<li>Templates 	unterstützen Vererbung.</li>
<li>Actions entsprechen 	Components (Components sind wiederverwendbar).</li>
<li>Kein sfWebRequest 	Objekt mehr. Ãœber das Routing werden Parameter direkt Ã¼bergeben.</li>
<li>Mit Doctrine 2 wird 	der Active Record Pattern durch den Entity Pattern ersetzt.</li>
<li>Nur noch einen 	Entity-Manager statt einer Factory (Table Object) pro Model.</li>
<li>Logger und Caches von 	Zend Framework.</li>
<li>Für Unit-Tests 	werden statt Lime PHPUnit Tests verwendet.</li>
<li>Mit PHP 5.3 	Verwendung von Namespaces etc.</li>
<li>Forms bestehen nicht 	mehr aus Widgets und Validatoren sondern aus Feldern mit Renderern 	und Validatoren).</li>
</ul>
<p>Es stellt sich die Frage ob so kurz vor einer grundlegend neuen Version nicht schon diese verwendet werden sollte. Nun, auf der Projekt-Homepage selbst steht, dass Symfony2.0 noch nicht reif ist für den produktiven Einsatz. Das Final-Release ist für ~März 2011 geplant. Es wird empfohlen neue Projekte, mindestens bis zu diesem Termin, mit Symfony 1.4 umzusetzen. Symfony 1.4 (aktuell 1.4.8) wird bis Ende 2012 unterstützt.</p>
<p>Von Symfony 1.0 ist bekannt dass erste Major-Release-Versionen noch voller Kinderkrankheiten stecken, welche erst nach Jahren zufriedenstellend beseitig werden. Symfony 1.4 hat diese Zeit erfolgreich gemeistert und eine treue Anhängerschaft um sich gebildet. Symfony2.0 steht hier noch am Anfang. Symfony versucht immer einen gewissen Grad an Updatefähig zu gewährleisten, vorausgesetzt die Entwickler halten sich so gut es geht an die vorgegebenen Konventionen. Auch kann man schon von vorn herein versuchen so zu entwickeln das ein evtl. Update später leichter möglich ist, wenn man sich  mit den Änderung in der Version 2.0 befasst (s.o.).</p>
<p>Kurzum ein neues Projekt sollte derzeit noch mit Symfony 1.4 umgesetzt werden, jedoch mit technischer Voraussicht auf Symfony2.0.<br />
<em></em></p>
<p><strong>Symfony2 Benchmark Results:</strong></p>
<p>For the &#8220;Product&#8221; application, Symfony2 is about:</p>
<ul style="text-align: left;">
<li><strong>50% 	faster</strong> than Yii 1.1.1</li>
<li><strong>2.5 	times faster</strong> than symfony 1.4.2</li>
<li><strong>3 	times faster</strong> than Zend 1.10</li>
<li><strong>6 	times faster</strong> than CakePHP 1.2.6</li>
</ul>
<p>Quelle: http://symfony-reloaded.org/fast</p>
<h2>Symfony Nachteile</h2>
<p>Symfony hat natürlich auch ein paar Nachteile die Beachtung finden sollten:</p>
<ul>
<li>Größe der 	Framework-Dateien ohne die Modelklassen: ~30MB.</li>
<li>Der Einstieg ist 	vergleichsweise aufwendig, da erst die Strukturen, 	Konfigurationsmöglichkeiten und nutzbaren Funktionen gelernt werden 	mÃ¼ssen.</li>
<li>Bei komplexeren 	Aufgaben kommt man nicht umhin sich mit dem Framework-Kern zu 	befassen.</li>
<li>Nicht dokumentierteÄ nderungen am Kern erschweren Framework-Updates.</li>
<li>Wenn kein Zugriff auf 	die Kommandozeile möglich ist muss ggf. ein Weg gefunden werden die 	Symfony-Tasks (Unit-Test, Model-Klassen generieren, Cache löschen 	etc.) auf anderem Wege auszuführen.</li>
<li>Symfony ist gerade 	auf dem Sprung in ein neues Major-Release, welches viele Äderungen 	mit sich bringt. Es kann sein dass die alte Community evtl. an 	Aktivität verliert.</li>
<li>Viele Vorteile des 	Frameworks (Admin-, Form- CRUD-Generator etc.) sind Abhängig von 	einem Datenbank-Modell.</li>
<li>Template-Files sind 	nicht alle in einem Verzeichnis. Grafiker müssen sich ggf. mit der 	Ordnerstruktur auskennen.</li>
<li>YAML-Konfigurations-Files 	sind sehr empfindlich gegenüber Tippfehlern (Leerzeichen).</li>
<li>Updates auf neue 	Versionen sind oft nicht ganz Problemlos.</li>
<li>Ungewolltes überschreiben von Konfigurationsdateien über die Hierarchieebenen.</li>
</ul>
<h2>Ist Symfony das richtige fÃ¼r einen Umstieg?</h2>
<p>Für einen kleinen Funktionsumfang wäre Symfony wahrscheinlich zu viel des Guten. Es wäre wohl damit getan sich auf eine Businesslogikstruktur zu einigen und ein Template-System zu integrieren. Doch die meisten Plattformen werden sich ohne Zweifel weiter entwickeln, um den professionellen Ansprüchen der Kunden gerecht  zu werden. Hier bietet Symfony bereits die nötige Schablone um solch ein Projekt Modul für Modul zu skalieren bis hin zu höchsten High-Demand-Anforderungen. Der Weg ist durch Symfony bereits geebnet und muss mit unseren Ideen nur noch befahren werden.</p>
<p>Es kam die Frage auf, ob man nicht evtl. nur Teile des Frameworks benutzen könnte. Eigentlich sind nahezu alle Symfony-Features für eine moderne Web-Anwendung essentiell. Trotzdem lassen sich über die tiefgreifenden Konfigurationsfiles die meisten Features einfach abschalten.</p>
<p>Natürlich darf dabei nicht vergessen werden, dass ein Framework auch Probleme mit sich bringen kann, wenn die Umgebung oder die Anforderung an das System zu speziell sind. Spontan stellen sich dann Symfony-Erfahrene die Frage nach der korrekten Funktionsweise des Symfony Caches, des Session-Management, Logging oder das Ausführen von Tasks, was bisher Konsolenzugriffe sowie ein beschreibbares Filessystem voraussetzt. Beantworten lässt sich die Frage mit den symfony-Factories, über die sich nahezu alle Standard-Handler, die für die genannten Funktionen zuständig sind, mit eigenen Lösungen Ã¼berschreiben oder anpassen lassen.</p>
<p>Symfony ist vielleicht nicht die schnellste Lösung, aber unter den umgesetzten Notwendigkeiten, um die eine Webapplikation nicht herumkommt, unübertroffen. Es lässt sich leicht hardwaretechnisch eine Performancesteigerung erreichen, aber es ist sehr schwer einen neuen Entwickler einem existierenden Projekt hinzuzufügen um es performanter zu machen.</p>
<h2>Quellen</h2>
<ul>
<li><a href="http://www.symfony-project.org">http://www.symfony-project.org</a></li>
<li><a href="http://www.symfony-project.org/blog/2007/10/02/delicious-preview-built-with-symfony">http://www.symfony-project.org/blog/2007/10/02/delicious-preview-built-with-symfony</a></li>
<li><a href="http://www.symfony-project.org/blog/2009/02/18/dailymotion-powered-by-symfony">http://www.symfony-project.org/blog/2009/02/18/dailymotion-powered-by-symfony</a></li>
<li><a href="http://www.symfony-project.org/blog/2008/05/08/yahoo-answers-powered-by-symfony">http://www.symfony-project.org/blog/2008/05/08/yahoo-answers-powered-by-symfony</a></li>
<li><a href="http://test.ical.ly/2010/03/05/symfony-2-wird-die-welt-retten-aber-was-soll-ich-bis-dahin-machen-teil-33-die-unterschiede/">http://test.ical.ly/2010/03/05/symfony-2-wird-die-welt-retten-aber-was-soll-ich-bis-dahin-machen-teil-33-die-unterschiede/</a></li>
<li><a href="http://www.karlkatzke.com/php-symfony-vs-zend/">http://www.karlkatzke.com/php-symfony-vs-zend/</a></li>
<li><a href="http://www.sensiolabs.com">http://www.sensiolabs.com</a></li>
</ul>
<h2>BÃ¼cher</h2>
<ul>
<li>A 	Gentle Introduction to Symfony 1.4 (ISBN-13: 978-2918390305)</li>
<li>More with Symfony 1.3 	&amp; 1.4 (ISBN-13: 978-2918390176)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/php-symfony-framework-pros-contras-zen/298/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Symfony: Propel: Criteria SQL (hibernate sql)</title>
		<link>http://blog.itopia.de/symfony-propel-criteria-sql-hibernate-sql/265</link>
		<comments>http://blog.itopia.de/symfony-propel-criteria-sql-hibernate-sql/265#comments</comments>
		<pubDate>Wed, 14 Apr 2010 16:34:41 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[criteria]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=265</guid>
		<description><![CDATA[Hi Volks, today I had a lot of testing with the symfony criteria object. And everyone who knows about the<a href="http://blog.itopia.de/symfony-propel-criteria-sql-hibernate-sql/265" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Hi Volks,</p>
<p>today I had a lot of testing with the symfony criteria object. And everyone who knows about the problem to get the raw SQL query out of the criteria object.</p>
<p>There is a toString method, but the result just looks like this:<br />
<code><br />
</code></p>
<pre class="brush:php">SELECT FROM media, media_category WHERE media.FEATURED=? AND media.MEDIATYPE IN (?,?) AND 1=1 AND media_category.CID NOT IN (?,?,?,?) AND media.MID=media_category.MID GROUP BY media.MID
Parameters to replace: array (
0 =&gt;
array (
'table' =&gt; 'media',
'column' =&gt; 'FEATURED',
'value' =&gt; true,
),
1 =&gt;
array (
'table' =&gt; 'media',
'column' =&gt; 'MEDIATYPE',
'value' =&gt; 'video',
),
2 =&gt;
array (
'table' =&gt; 'media',
'column' =&gt; 'MEDIATYPE',
'value' =&gt; 'audio',
),
3 =&gt;
array (
'table' =&gt; 'media_category',
'column' =&gt; 'CID',
'value' =&gt; 10,
),
4 =&gt;
array (
'table' =&gt; 'media_category',
'column' =&gt; 'CID',
'value' =&gt; 9,
),
5 =&gt;
array (
'table' =&gt; 'media_category',
'column' =&gt; 'CID',
'value' =&gt; 4,
),
6 =&gt;
array (
'table' =&gt; 'media_category',
'column' =&gt; 'CID',
'value' =&gt; 7,
)
)</pre>
<p>And it is very strange to fill the question marks by hand with the related values from the parameters array.</p>
<p>So I wrote a function which does this for me:</p>
<pre class="brush:php">function getCriteriaSQL($c, $select = '*')
{
$params = array();
$r = BasePeer::createSelectSql($c, $params);
$o = str_replace('?', '%s', $r);

$ggg = array();
foreach($params AS $e)
{
if(is_integer($e['value']) OR is_bool($e['value']))
{
$ggg[] = $e['value'];
}
else
{
$ggg[] = "'".$e['value']."'";
}
}

$sql = vsprintf($o, $ggg);

$sql = str_replace('SELECT ', 'SELECT '.$select, $sql);

return $sql;
}</pre>
<p>I just wanted to share this with you and I appreciate your comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/symfony-propel-criteria-sql-hibernate-sql/265/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfony: How to build a dojo dijit autocompleter sfForm widget</title>
		<link>http://blog.itopia.de/symfony-how-to-dojo-dijit-autocompleter-sfform-widget/260</link>
		<comments>http://blog.itopia.de/symfony-how-to-dojo-dijit-autocompleter-sfform-widget/260#comments</comments>
		<pubDate>Thu, 29 Oct 2009 13:20:36 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[AJAX/AXAH]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[autocompleter]]></category>
		<category><![CDATA[dijit]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[sfform]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=260</guid>
		<description><![CDATA[I was searching long time for a good auto completer widget, but I couldn&#8217;t find one. So I created it<a href="http://blog.itopia.de/symfony-how-to-dojo-dijit-autocompleter-sfform-widget/260" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>I was searching long time for a good auto completer widget, but I couldn&#8217;t find one. So I created it by my self.<br />
I did the same with the build in symfony auto completer widget. When I have time I&#8217;ll post it, too.<br />
I hope I could help someboby with this small tutorial. Please give me feedback if there are any questions or suggestions.</p>
<p>Now lets start:</p>
<p><strong>1. Copy the dojo package to the js folder</strong><br />
Resulting path to dojo.js: <em>web/js/dojoToolkit/dojo/dojo.js</em></p>
<p><strong>2. Enable dojo.js</strong><br />
If not yet happend elsewhere:<br />
Modify the view.yml: <em>apps/[YOUR_APP]/config/view.yml</em><br />
<code><br />
</code></p>
<pre class="brush:plain">default:
javascripts: [dojoToolkit/dojo/dojo.js]</pre>
<p><strong>3. Create the widget</strong><br />
<em>lib/widget/itWidgetFormInputTextDijitAutocomplete.php</em></p>
<pre class="brush:php">class itWidgetFormInputTextDijitAutocomplete extends sfWidgetForm
{
/**
* Constructor.
*
* Available options:
*
* * model: Name of the Model
* * searchfield: Table field in which will be searched
* * action: Optional: request action or url
* * value_method: Optional: getter for form field value
* * output_method: Optional: getter for form field name
* * criteria_method: Optional: getter for additional cirteria
* * add_empty: Optional: add emtpy value option to the list
* * choices: An array of possible choices (n/a)
* * formatter: A callable to call to format the checkbox choices
*
* @see sfWidgetForm
*/
protected function configure($options = array(), $attributes = array())
{
$this-&gt;addRequiredOption('model');
$this-&gt;addRequiredOption('search_field');
$this-&gt;addOption('action', 'default/ajaxAutocomplete');
$this-&gt;addOption('value_method', 'getPrimaryKey');
$this-&gt;addOption('output_method', 'getPrimaryKey');
$this-&gt;addOption('choices', array());
$this-&gt;addOption('criteria_method', '');
$this-&gt;addOption('formatter', array($this, 'formatter'));
$this-&gt;addOption('add_empty', false);
}

/**
* Renders the widget as HTML.
*
* @param string The name of the HTML widget
* @param mixed The value of the widget
* @param array An array of HTML attributes
* @param array An array of errors
*
* @return string A HTML representation of the widget
*
* @see sfWidgetForm
*/
public function render($name, $value = null, $attributes = array(), $errors = array())
{
$choices = $this-&gt;getOption('choices');
if ($choices instanceof sfCallable)
{
$choices = $choices-&gt;call();
}

$baseAttributes = array(
'action' =&gt; $this-&gt;getOption('action'),
'name' =&gt; $name,
'type' =&gt; 'text',
'value' =&gt; $value,
'id' =&gt; $id = $this-&gt;generateId($name, self::escapeOnce($name)),
);

return call_user_func($this-&gt;getOption('formatter'), $this, $baseAttributes);
}

/**
* Renders the input fields as HTML.
*
* @param widget
* @param attributes
*
* @return string A HTML representation of the input fields
*/
public function formatter($widget, $attributes)
{
sfLoader::loadHelpers(array('Form', 'Url'));
$request = sfContext::getInstance()-&gt;getRequest();
$field_id = $attributes['id'];
$field_name = $attributes['name'];
$ajax_field_id = 'ajax_'.$attributes['id'];
$out_field_id = 'out_'.$attributes['id'];
$object = @call_user_func(array($this-&gt;getOption('model').'Peer', 'retrieveByPk'), $attributes['value']);
$default_out = $request-&gt;getParameter('ajax_'.$attributes['name'], is_object($object) ? call_user_func(array(&amp;$object, $this-&gt;getOption('output_method'))) : '');
$default_value = $request-&gt;getParameter($attributes['name'], is_object($object) ? $attributes['value'] : '');

$html = '';
$ajaxParams=array(
'model' =&gt; $this-&gt;getOption('model'),
'value_method' =&gt; $this-&gt;getOption('value_method'),
'output_method' =&gt; $this-&gt;getOption('output_method'),
'search_field' =&gt; $this-&gt;getOption('search_field'),
'criteria_method' =&gt; $this-&gt;getOption('criteria_method'),
'field_name' =&gt; 'ajax_'.$attributes['name']
);
if($this-&gt;getOption('add_empty')===false) $ajaxParams['add_empty'] = 'false';
elseif($this-&gt;getOption('add_empty')===true) $ajaxParams['add_empty'] = 'true';
else $ajaxParams['add_empty'] = $this-&gt;getOption('add_empty');

$requestUrl = url_for($attributes['action'].'?'.http_build_query($ajaxParams), true);
$requestUrl = str_replace('frontend_dev.php/', '', $requestUrl);
$requestUrl = str_replace('backend_dev.php/', 'backend.php/', $requestUrl);

$html .= &lt;&lt;
&lt;script type="text/javascript"&gt;
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.form.FilteringSelect");
&lt;/script&gt;
&lt;div dojoType="dojo.data.ItemFileReadStore"
jsId="{$field_id}Store" url="{$requestUrl}"&gt;&lt;/div&gt;
EOF;

$input_text = &lt;&lt;
&lt;input dojoType="dijit.form.FilteringSelect"
store="{$field_id}Store"
class="medium"
id="{$field_id}"
name="{$field_name}"
value="{$default_value}"
hasDownArrow="true",
invalidMessage="",
ignoreCase="true" /&gt;
}</pre>
<p><strong>4. Create action for the AJAX request</strong><br />
<em>apps/[APP_NAME]/modules/default/actions/actions.class.php</em></p>
<pre class="brush:php">&lt;?php
class defaultActions extends sfActions
{
public function executeAjaxAutocomplete($request)
{
$model = $request-&gt;getParameter('model');
$criteria_method = $request-&gt;getParameter('criteria_method');
$add_empty = $request-&gt;getParameter('add_empty', 'false');
$this-&gt;value_method = $request-&gt;getParameter('value_method');
$this-&gt;output_method = $request-&gt;getParameter('output_method');

$peer_object = $model.'Peer';

if($criteria_method!='') $criteria = call_user_func(array($peer_object, $criteria_method));
else $criteria = new Criteria();

$search_field = $request-&gt;getParameter('search_field');
$field_name = $request-&gt;getParameter('field_name');
$var = $request-&gt;getParameter($field_name);

$j_object = array('identifier' =&gt; 'abbreviation', 'items'=&gt;array());

$search_field = strtoupper($search_field);

$sql_field = constant($peer_object.'::'.$search_field);

$c = $criteria;
$c-&gt;add($sql_field, $var . '%', Criteria::LIKE);
$this-&gt;list = call_user_func(array($peer_object,'doSelect'), $c);

if($add_empty!='false')
{
$j_object['items'][] = array(
'name' =&gt; $add_empty=='true' ? '' : $add_empty,
'label' =&gt; '',
'abbreviation' =&gt; ''
);
}

foreach($this-&gt;list AS $v)
{
$j_object['items'][] = array(
'name' =&gt; call_user_func(array(&amp;$v, $this-&gt;output_method)),
'label' =&gt; call_user_func(array(&amp;$v, $this-&gt;output_method)),
'abbreviation' =&gt; call_user_func(array(&amp;$v, $this-&gt;value_method))
);
}
$this-&gt;j_object = $j_object;
}
}</pre>
<p><strong>5. Create template for the AJAX request</strong><br />
<em>apps/[APP_NAME]/modules/default/templates/ajaxAutocompleteSuccess.php</em><br />
<code></p>
<pre class="brush:php">&lt;?php decorate_with(false); ?&gt;
&lt;?php print_r(json_encode($j_object)); ?&gt;</pre>
<p></code></p>
<p><strong>6. Insert the new widget into your sfForm</strong><br />
<em>apps/[APP_NAME]/modules/default/templates/ajaxAutocompleteSuccess.php</em><br />
<code></p>
<pre class="brush:php">...
# $widgets['user_id'] = new sfWidgetFormInput();
$widgets['user_id'] = new stWidgetFormInputTextDijitAutocomplete(array(
'model' =&gt; 'User',
'search_field' =&gt; 'username',
'value_method' =&gt; 'getId',
'output_method' =&gt; 'getUsername',
'criteria_method' =&gt; 'getCriteriaRegisteredUsers'
));</pre>
<p></code></p>
<p><strong>6. Clear symfony cache</strong></p>
<p><strong>Links:</strong></p>
<ul>
<li>http://api.dojotoolkit.org/jsdoc/1.3.2/dijit.form.FilteringSelect</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/symfony-how-to-dojo-dijit-autocompleter-sfform-widget/260/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: String nach Wortende kÃ¼rzen</title>
		<link>http://blog.itopia.de/php-string-nach-wortende-kurzen/256</link>
		<comments>http://blog.itopia.de/php-string-nach-wortende-kurzen/256#comments</comments>
		<pubDate>Tue, 17 Feb 2009 10:53:12 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[substr]]></category>
		<category><![CDATA[Wortende]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=256</guid>
		<description><![CDATA[Das Problem hatte vielleicht schon manch einer. Hier eine LÃ¶sung: function getShortTextByWord($string, $len) { $string = substr($string, 0, $len); $string_end<a href="http://blog.itopia.de/php-string-nach-wortende-kurzen/256" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Das Problem hatte vielleicht schon manch einer. Hier eine LÃ¶sung:</p>
<p><code>function getShortTextByWord($string, $len)<br />
  {<br />
    $string = substr($string, 0, $len);<br />
    $string_end = strrpos($string, ' ');<br />
    if($string_end) $string = substr($string, 0, $string_end);<br />
    return $string;<br />
  }</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/php-string-nach-wortende-kurzen/256/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP, RegExp: Match exact string with preg_replace</title>
		<link>http://blog.itopia.de/php-regexp-match-exact-string-with-preg_replace/120</link>
		<comments>http://blog.itopia.de/php-regexp-match-exact-string-with-preg_replace/120#comments</comments>
		<pubDate>Tue, 20 May 2008 08:03:41 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[RegExp]]></category>
		<category><![CDATA[preg_replace]]></category>
		<category><![CDATA[Regular Expression]]></category>
		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/2008/05/20/php-regexp-match-exact-string-with-preg_replace/</guid>
		<description><![CDATA[Kurz um, um einen exakten String zu ersetzten, muss man preg_replace mit dem &#8220;\b&#8221; &#8211; Parameter (word boundary) benutzen: $new_string<a href="http://blog.itopia.de/php-regexp-match-exact-string-with-preg_replace/120" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Kurz um, um einen exakten String zu ersetzten, muss man <a href="de.php.net/preg_replace">preg_replace</a> mit dem &#8220;<strong>\b</strong>&#8221; &#8211; Parameter (<strong>word boundary</strong>) benutzen:</p>
<p><code>$new_string = preg_replace('/\b'.$exact_string.'\b/', $replace_with);</code></p>
<p>Ich kannte es sonst nur so:</p>
<p><code>$new_string = preg_replace('^'.$exact_string.'$', $replace_with);</code></p>
<p>Das warf bei mir aber immer den Fehler:</p>
<p><code>Warning: preg_replace() [function.preg-replace]: No ending delimiter '^' found in /home/....php on line ...</code></p>
<p>Einige werden sagen, warum macht er das denn nicht mit dem viel performanteren <a href="http://de.php.net/manual/de/function.str-replace.php">str_replace</a>?<br />
Ich nehme <strong>preg_replace</strong>, weil ich in dem Ã¼bergebenen String den zu ersetzenden Teilstring nur einmal ersetzen will.<br />
Als dritten Parameter kann man angeben wie oft der Teilstring ersetzt werden soll.</p>
<p><code>$new_string = preg_replace('/\b'.$exact_string.'\b/', $replace_with,1);</code></p>
<p>Wenn es <strong>case insensitive</strong> sein soll einfach ein &#8220;<strong>i</strong>&#8221; anhÃ¤ngen:</p>
<p><code>$new_string = preg_replace('/(\b'.$exact_string.'\b)/i', $replace_with);</code></p>
<p><strong>Edit:</strong></p>
<p>PlÃ¶tzlich tauchte diese Warnung bei der Ãœbergabe eines ganz normalen Strings auf:</p>
<p><code>preg_replace() [function.preg-replace]: Unknown modifier 't'</code></p>
<p>Abhilfe schaffte die Ã„nderung der Delimiter von Slash (/) auf Pipe (|):</p>
<p><code>$new_string = preg_replace('|(\b'.$exact_string.'\b)|i', $replace_with);</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/php-regexp-match-exact-string-with-preg_replace/120/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript: unterminated string literal</title>
		<link>http://blog.itopia.de/javascript-unterminated-string-literal/114</link>
		<comments>http://blog.itopia.de/javascript-unterminated-string-literal/114#comments</comments>
		<pubDate>Tue, 06 May 2008 08:35:52 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Error]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/2008/05/06/javascript-unterminated-string-literal/</guid>
		<description><![CDATA[Was hab ich mich damit rum geschlagen und kein einziges Suchergebnis bei g* konnte mir die LÃ¶sung bieten. Kurz zum<a href="http://blog.itopia.de/javascript-unterminated-string-literal/114" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Was hab ich mich damit rum geschlagen und kein einziges Suchergebnis bei g* konnte mir die LÃ¶sung bieten.<br />
Kurz zum Problem. Ich lese mit PHP Text aus einer MySQL-Datenbank, welcher auch ZeilenumbrÃ¼che enthalten kann.<br />
Diese ZeilenumbrÃ¼che werden mit </p>
<p><code>\n</code> </p>
<p>oder </p>
<p><code>\r\n</code> </p>
<p>codiert. Ich weiÃŸ, dass in JS ZeilenumbrÃ¼che in Strings verboten sind und wollte diese nun ersetzten. DafÃ¼r gibt es mich folgende MÃ¶glichkeiten:</p>
<ul>
<li><a href="http://de.php.net/manual/de/function.nl2br.php">php: nl2br</a></li>
<li><a href="http://de.php.net/manual/de/function.str-replace.php">php: str_replace</a></li>
<li><a href="http://de.php.net/manual/de/function.preg-replace.php">php: preg_replace</a></li>
</ul>
<p><em>nl2br</em> brachte nichts und kann in der AusfÃ¼hrung auch nicht wirklich beeinflusst werden. Ok dann  mit <em>str_replace</em> oder <em>preg_replace</em>.<br />
Was ich versucht habe war nun folgendes:</p>
<p><code>$str = str_replace('\r\n','<br />',$str);<br />
$str = str_replace('\r','<br />',$str);<br />
$str = str_replace('\n','<br />',$str);</code></p>
<p>Nichts hat geholfen, der Fehler war noch da und der Umbruch war sogar noch im Quellcode zu sehen.<br />
Dann fiehl mir Gott sei Dank ein, dass PHP einen Unterschied macht ob man SingleQuotes (&#8216;) oder DoubleQuotes (&#8220;) benutzt. Code in SingleQuotes wird bspw. nicht nach PHP-Variablen geparst. Also versuchte ich es mal so:</p>
<p><code>$str = str_replace("\r\n","<br />",$str);</code></p>
<p>Und siehe da, die Sonderzeichen wurden wie gewÃ¼nscht ersetzt und der JavaScript-Fehler <strong>unterminated string literal</strong> war verschwunden. Bitte. Danke.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/javascript-unterminated-string-literal/114/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP, MySQL: Datensatz innerhalb einer Tablle kopieren</title>
		<link>http://blog.itopia.de/php-mysql-datensatz-innerhalb-einer-tablle-kopieren/50</link>
		<comments>http://blog.itopia.de/php-mysql-datensatz-innerhalb-einer-tablle-kopieren/50#comments</comments>
		<pubDate>Thu, 05 Oct 2006 14:53:42 +0000</pubDate>
		<dc:creator>TBA</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Weblog]]></category>

		<guid isPermaLink="false">http://blog.itopia.de/?p=50</guid>
		<description><![CDATA[Da es ja eigentlich nicht erlaubt ist einen Datensatz innerhalb einer Tabelle zu kopieren. Z.B. per INSERT INTO tablle(Felder_ohne_Primary_Key) SELECT<a href="http://blog.itopia.de/php-mysql-datensatz-innerhalb-einer-tablle-kopieren/50" class="searchmore">Read the Rest...</a><div class="clr"></div>]]></description>
			<content:encoded><![CDATA[<p>Da es ja eigentlich nicht erlaubt ist einen Datensatz innerhalb einer Tabelle zu kopieren. Z.B. per </p>
<blockquote><p>INSERT INTO tablle(<em>Felder_ohne_Primary_Key</em>) SELECT <em>Felder_ohne_Primary_Key</em> WHERE <em>Primary_Key</em>=<em>Wert_des_zu_kopiernenden_Datensatzes</em></p></blockquote>
<p>weil die Datenbank die Abfragen dann nicht mehr korrekt trennen kann, habe ich eine kleine Funktion geschrieben, welches dies, ohne die Regeln zu verletzten durchfÃ¼hrt und die ID bzw. den Wert des Primary Keys des neuen Datensatzes zurÃ¼ckliefert:</p>
<p>[syntax,copy_mysql_dataset.php,php]</p>
<p>Man kann sicher hier und da ein paar Sachen einfacher programmieren, ich freue mich Ã¼ber Feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itopia.de/php-mysql-datensatz-innerhalb-einer-tablle-kopieren/50/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

