<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>symfonynerds.com</title>
	
	<link>http://symfonynerds.com/blog</link>
	<description>Nerds who love the symfony-project</description>
	<lastBuildDate>Thu, 15 Apr 2010 02:06:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/symfony" /><feedburner:info uri="symfony" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>symfony</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Zend Webinar: The road to faster development</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/1vxvAuC5Kfw/</link>
		<comments>http://symfonynerds.com/blog/?p=371#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:04:15 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[community]]></category>
		<category><![CDATA[symfony community]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=371</guid>
		<description><![CDATA[Disclaimer: I work for Atlassian. I thought I&#8217;d post this to the Symfony community because we know Symfony can work really well with Zend and I wanted to know what development tools our readers use in their Symfony projects. What to know what tools Zend use? The Zend team are organising a webinar with Atlassian [...]]]></description>
			<content:encoded><![CDATA[<p><em>Disclaimer:</em> I work for <a href="http://atlassian.com">Atlassian</a>. I thought I&#8217;d post this to the Symfony community because we know <a href="http://www.symfony-project.org/book/1_2/17-Extending-Symfony#chapter_17_integrating_with_other_framework_s_components">Symfony can work really well with Zend</a> and I wanted to know what development tools our readers use in their Symfony projects.<br />
What to know what tools Zend use? The Zend team are organising a webinar with Atlassian &#8211; looking at the tools they use to speed up their application development life-cycle. Here is the blurb:</p>
<blockquote><p>Creating a comprehensive unit test suite is an important step towards  producing stable, high-quality PHP code. It will also help you set the  foundation for using continuous integration, which provides fast  feedback about the impact of code changes and can help prevent  unexpected project delays.</p>
<p>Join this webinar by Atlassian and  Zend to learn about unit testing and continuous integration, and see  live demonstrations of how you can quickly adopt both practices using  Zend Studio and Atlassian Bamboo.</p></blockquote>
<p>Zend <a href="http://www.atlassian.com/tv/episode?id=ooed4kounrc7">recently switched</a> their <a href="http://www.atlassian.com/tv/episode?id=ooed4kounrc7">Issue Tracker</a> to <a href="http://atlassian.com/jira">JIRA</a>, <a href="framework.zend.com/fisheye">Source control analytics to Fisheye</a> and <a href="http://framework.zend.com/wiki/display/ZFDEV/Home">Wiki</a> to <a href="http://atlassian.com/confluence">Confluence</a>. All of these <a href="http://www.atlassian.com/opensource/">are free tools by Atlassian &#8211; if you run an Open Source project</a>.</p>
<p>The Zend team will be sharing on how the use <a href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> for continuous  integration. You can <a href="http://www.zend.com/en/company/news/event/webinar-the-road-to-faster-development-unit-testing-and-continuous-integration">read  more about the Webinar and register here</a>.</p>
<p>In the Symfony world the <a href="http://www.doctrine-project.org">Doctrine project</a> also runs an <a href="http://www.doctrine-project.org/jira/secure/Dashboard.jspa">Open Source license of JIRA</a>. <a href="http://trac.symfony-project.org/timeline">The Symfony project itself uses Trac</a>, which is also a very popular open source issue tracker.</p>
<p>I&#8217;m interested to know &#8211; what development tools do you use to speed up your development? (Issue tracking, source control, wikis, continuous builds and integration). How do you find them?</p>
<p>In particular, I&#8217;d love to hear if you use continuous integration and builds in your PHP coding. Is this mostly a JAVA or .NET thing or is it taking off in the scripting world as well?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=1vxvAuC5Kfw:IRR8Xy4ike4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=1vxvAuC5Kfw:IRR8Xy4ike4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=1vxvAuC5Kfw:IRR8Xy4ike4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=1vxvAuC5Kfw:IRR8Xy4ike4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/1vxvAuC5Kfw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=371</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=371</feedburner:origLink></item>
		<item>
		<title>Symfony Best Practise : Designing your Schema</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/RAW2mbLKoCo/</link>
		<comments>http://symfonynerds.com/blog/?p=366#comments</comments>
		<pubDate>Sat, 27 Feb 2010 13:34:34 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[tip]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[schema.yml]]></category>
		<category><![CDATA[workbench]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=366</guid>
		<description><![CDATA[In our team, we&#8217;ve been using Symfony since version 1.0, and ever since we started we&#8217;ve been evolving the way we work. For a little while I&#8217;ve been thinking of writing a &#8220;best practice&#8221; series, not to say this is the way you MUST do things, but to point out some of the things that [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.youtube.com/watch?v=rcKuXW0j_94" target="_blank">our team</a>, we&#8217;ve been using Symfony since version 1.0, and ever since we started we&#8217;ve been evolving the way we work. For a little while I&#8217;ve been thinking of writing a &#8220;best practice&#8221; series, not to say this is the way you MUST do things, but to point out some of the things that have worked for us, and more than anything, to spark some conversation about what works for you.</p>
<p>It&#8217;s always best to start at the beginning, and for most Symfony (or any) web apps, this is often with designing your schema (ignoring requirements gathering, but who really cares what your users want <img src='http://symfonynerds.com/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</p>
<p>Our approach here can be summed up in one word: <a href="http://exacterm.files.wordpress.com/2009/08/terminology-workbench.jpg" target="_blank">Workbench</a>. Ok maybe two: <a href="http://wb.mysql.com/" target="_blank">MySQL Workbench</a>.</p>
<p>Yes this is only usefull for MySQL databases, but as our <a href="http://symfonynerds.com/blog/?p=227" target="_blank">2009 survey</a> showed, this is far an away the most popular DB used with Symfony.</p>
<p>Maybe you really love writing your schema.yml and wouldn&#8217;t dream of doing it any other way, but personally, I find working with the visual representation of my schema to be a lot faster and generally delivers a much better result &#8211; there&#8217;s something about &#8216;seeing&#8217; it that makes it easier to design. </p>
<p>Apart from this (and some people I know genuinely prefer to write their schema file by hand) there are probably three more REALLY good reasons to give this a try:</p>
<p><strong>Consistency</strong><br />
As I talked about <a href="http://symfonynerds.com/blog/?p=250">here</a> CaMeL cAsE matters. If you try and chop and change between a forward and reverse engineered DB/schema.yml you are almost guaranteed to run into trouble where someone has named something outside of the convention Symfony will use in a reverse engineer of the DB. Starting with and sticking to a process of reverse engineering your schema.yml (then model, forms &#038; filters) from the DB will ensure consistency.</p>
<p><strong>Upgrading</strong><br />
One of the seriously, <strong>seriously</strong> cool features of Workbench is that it can generate a MySQL &#8216;upgrade&#8217; script for you. You can give it another Workbench file (eg: an older version of your schema) or a DB to connect to then compare it to your latest version and it will generate the &#8216;alter&#8217; script for you to upgrade your DB. This is awesome for the real world where you don&#8217;t want to have to blow away and reload your database (leading to extra production downtime) if you don&#8217;t have to. In the case of an upgrade where only new tables or columns are added this becomes so simple it&#8217;s incredible. As some of you will know once your DB gets too big fixtures will no longer help you, in this case this is even more valuable.</p>
<p><strong>Speed &#038; Safety</strong><br />
Since Workbench allows you to connect to a MySQL server and &#8216;forward engineer&#8217; (or reverse if you want it initially) you quickly realise the fastest as well as safest way to make schema changes to your app is really to do it in Workbench, forward engineer it to your DB, then rebuild your schema, model, forms &#038; filters. The best processes in the world usually fail if they are hard to implement, but so far I&#8217;ve found doing things the right way has also been the easiest.</p>
<p>So, how do you go about designing your schema? Do you have a better method, or are you keen to give Workbench a workout?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=RAW2mbLKoCo:u2AS_wd_kXg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=RAW2mbLKoCo:u2AS_wd_kXg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=RAW2mbLKoCo:u2AS_wd_kXg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=RAW2mbLKoCo:u2AS_wd_kXg:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/RAW2mbLKoCo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=366</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=366</feedburner:origLink></item>
		<item>
		<title>Symfony Experts is a new site for urgent Symfony questions</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/Q8w5XJFWsgs/</link>
		<comments>http://symfonynerds.com/blog/?p=359#comments</comments>
		<pubDate>Sun, 21 Feb 2010 07:20:29 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[community]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=359</guid>
		<description><![CDATA[Darren Hoyt and I are looking for some Symfony programmers to answer questions on our new Symfony site. Darren and I are often asked for help with small programming or design tasks, simple problems that require maybe 5 minutes of our time. Since we do a lot of work with WordPress, we recently built WP [...]]]></description>
			<content:encoded><![CDATA[<p>Darren Hoyt and I are looking for some Symfony programmers to answer questions on <a href="http://www.symfonyexperts.com/">our new Symfony site</a>. </p>
<p>Darren and I are often asked for help with small programming or design tasks, simple problems that require maybe 5 minutes of our time. Since we do a lot of work with WordPress, we recently built <a href="http://www.wpquestions.com/">WP Questions</a>, a place where WordPress experts can earn some money by answering people&#8217;s emergency questions about WordPress.</p>
<p>Today we are launching <a href="http://www.symfonyexperts.com/">Symfony Experts</a>, which is the same kind of site, but aimed at Symfony.</p>
<p>We have a bit of a chicken-and-egg problem when launching these sites, since the experts aren&#8217;t interested till their are customers and the customers aren&#8217;t interested till their are experts. Still, our preference is to get some experts signed up first, before we start marketing this thing heavily to all programmers working with Symfony. Please consider signing up now. Once we have about 10 good Symfony programmers signed up, we&#8217;ll begin marketing the site. It is free to sign up.</p>
<p>The people asking the questions put up prize money for whoever answers them. You can look at WP Questions to see the kinds of money people has so far offered. </p>
<p><a href="http://blog.symfonyexperts.com/?p=4">More details are here</a>.</p>
<p>For our customers who are paying to ask questions, <a href="http://www.symfonyexperts.com/page/static/name/HowToAskAQuestion">this tutorial explains how to ask a question</a>.</p>
<p>For our customers who are paying to ask questions, <a href="http://www.symfonyexperts.com/page/static/name/HowToAssignPrizeMoney">this tutorial explains how to assign prize money to an expert who has answered your question</a>.</p>
<p>We are happy, even eager, to share our revenue with those of you who can send us some users, so <a href="http://www.symfonyexperts.com/page/static/name/Affiliates">we have a variety of affiliate programs</a>. </p>
<p>By the way, next month we will be launching similar sites for MySql and Javascript. And in a bit of what the engineers at Microsoft would call &#8220;eat your own dog food&#8221; I&#8217;ll be posting a bunch of questions on Symfony Experts, to get advice about how to build out our network of sites. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=Q8w5XJFWsgs:1aZVUvYnu_Q:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=Q8w5XJFWsgs:1aZVUvYnu_Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=Q8w5XJFWsgs:1aZVUvYnu_Q:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=Q8w5XJFWsgs:1aZVUvYnu_Q:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/Q8w5XJFWsgs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=359</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=359</feedburner:origLink></item>
		<item>
		<title>Kris Wallsmith on Symfony in the clouds</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/r_aQuhms0Pc/</link>
		<comments>http://symfonynerds.com/blog/?p=357#comments</comments>
		<pubDate>Sun, 21 Feb 2010 03:13:47 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[configuration]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=357</guid>
		<description><![CDATA[Scott Meves points me to this presentation by Kris Wallsmith. Lots of information about how to scale up Symfony, and a plugin is thrown in for handling multiple database connections. I&#8217;ve not yet dealt with a site on that scale, but this looks like a very promising way to scale up, whenever I&#8217;m confronted by [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://stereointeractive.com/">Scott Meves</a> points me to <a href="http://www.slideshare.net/kriswallsmith/symfony-in-the-cloud">this presentation by Kris Wallsmith</a>. Lots of information about how to scale up Symfony, and a plugin is thrown in for handling multiple database connections. I&#8217;ve not yet dealt with a site on that scale, but this looks like a very promising way to scale up, whenever I&#8217;m confronted by that kind of demand. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=r_aQuhms0Pc:LiRdrfuIyAI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=r_aQuhms0Pc:LiRdrfuIyAI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=r_aQuhms0Pc:LiRdrfuIyAI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=r_aQuhms0Pc:LiRdrfuIyAI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/r_aQuhms0Pc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=357</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=357</feedburner:origLink></item>
		<item>
		<title>In Symfony, how big should a module be?</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/yktQR10rcJI/</link>
		<comments>http://symfonynerds.com/blog/?p=339#comments</comments>
		<pubDate>Sun, 21 Feb 2010 02:32:50 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[Symfony MVC]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=339</guid>
		<description><![CDATA[How big should a module be in Symfony? I&#8217;ve been re-thinking this issue in light of what I&#8217;ve been reading about RESTful architectures. For awhile now, Symfony has been moving toward enabling a RESTful architecture. As Fabien Potencier wrote a year ago: The sfRequestRoute is the first step towards a RESTful architecture. See also this [...]]]></description>
			<content:encoded><![CDATA[<p>How big should a module be in Symfony? I&#8217;ve been re-thinking this issue in light of what I&#8217;ve been reading about RESTful architectures. </p>
<p>For awhile now, Symfony has been moving toward enabling a RESTful architecture. <a href="http://www.symfony-project.org/blog/2008/09/04/new-in-symfony-1-2-toward-a-restful-architecture-part-1">As Fabien Potencier wrote a year ago</a>: </p>
<blockquote><p>The sfRequestRoute is the first step towards a RESTful architecture.</p></blockquote>
<p><a href="http://fabien.potencier.org/talk/16/symfony-camp-2008-REST?position=4">See also this talk he gave</a>. </p>
<p>What is a RESTful architecture and what is it useful for? The best answer to both questions comes from the book <a href="http://www.amazon.com/Restful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1266713961&amp;sr=8-1">Restful Web Services</a> by <a href="http://www.crummy.com/">Leonard Richardson</a> and <a href="http://intertwingly.net/blog/">Sam Ruby</a> (published May of 2007). Though the phrase &#8220;RESTful&#8221; actually comes from <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">Roy Fielding&#8217;s Phd dissertation</a>, I think it is reasonable to say that the popularization of the term come from what those 2 men wrote on their blogs in 2006 and 2007, and then from the book they jointly produced. </p>
<p><a href="http://www.amazon.com/Restful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1266713961&amp;sr=8-1"><img src="http://symfonynerds.com/blog/wp-content/uploads/2010/02/restful_web_services.jpg" alt="" width="240" height="240" class="alignnone size-full wp-image-340" /></a></p>
<p>Their writing arose at first in opposition to what had become known as &#8220;Web Services&#8221;. That style of architecture focused on delivering XML via an HTTP request and then interpreting the payload via protocols that had become horribly complex. For an excellent parody, read &#8220;<a href="http://72.249.21.88/nonintersecting/2006/11/15/the-s-stands-for-simple/?year=2006&amp;monthnum=11&amp;day=15&amp;name=the-s-stands-for-simple&amp;page=">The S stands for Simple</a>&#8221; by Pete Lacey, which creates an imaginary conversation between a developer and an evangelist for the SOAP protocol. Lacey&#8217;s criticism is the same one that Richardson and Ruby are making: </p>
<blockquote><p>Dev: Hrrm. And what happens if I move the service to a different endpoint? Do I get a 301 back?</p>
<p>SG: No. SOAP doesn’t really use HTTP response codes.</p>
<p>Dev: So, when you said SOAP uses HTTP, what you meant to say is SOAP tunnels over HTTP.</p>
<p>SG: Well, ‘tunnel’ is such an ugly word. We prefer to say SOAP is transport agnostic.</p>
<p>&#8230;</p>
<p>Dev: I’ll note that your entire industry is built around ambiguous, sometimes erroneous, and definitely not standardized specifications. In fact, the SOAP and WSDL specs are just W3C Notes, not even working drafts.</p></blockquote>
<p>Against this bloated, overly-complicated style, Richardson and Ruby set out to remind people what made the Web such a big success in the first place (Preface, page xiii): </p>
<blockquote><p>It may seem strange to claim that the Web&#8217;s potential for distributed programming has been overlooked. After all, this book competes for shelf space with any number of other books about web services. The problem is, most of today&#8217;s &#8220;web services&#8221; have nothing to do with the web. In opposition to the Web&#8217;s simplicity, the espouse a heavyweight architecture for distributed object access, similar to COM or CORBRA. Today&#8217;s &#8220;web service&#8221; architectures reinvent or ignore every feature that makes the Web successful. </p>
<p>It doesn&#8217;t have to be that way. We know the technologies behind the Web can drive useful remote services, because those services exist and we use them every day. We know such services can scale to enormous size, because they already do. Consider the Google search engine. What is it but a remote service for querying a massive database and getting back a formatted response? We don&#8217;t normally think of web sites as &#8220;services,&#8221; because that&#8217;s programming talk and a web site&#8217;s ultimate client is a human, but services are what they are. </p>
<p>Every web application &#8211; every web site &#8211; is a service. You can harness this power for programmable applications if you work with the Web instead of against it, if you don&#8217;t bury its unique power under layers of abstraction. It&#8217;s time to put the &#8220;web&#8221; back in &#8220;web services&#8221;. </p>
<p>The features that make a web site easy for a web surfer to use also make a web service API easy for a programmer to use. To find the principles underlying the design of these services, we can just translate the principles for human-readable web sites into terms that make sense when the surfers are computer programmers. </p></blockquote>
<p>They then summarize some of the &#8220;weaknesses&#8221; in the HTTP protocol, and they point out that these weaknesses are really strengths. They reference what <a href="http://www.shirky.com/writings/evolve.html">Clay Shirky has written on this subject</a>: </p>
<blockquote><p>If it were April Fool&#8217;s Day, the Net&#8217;s only official holiday, and you wanted to design a &#8216;Novelty Protocol&#8217; to slip by the Internet Engineering Task Force as a joke, it might look something like the Web:</p>
<p>The server would use neither a persistent connection nor a store-and-forward model, thus giving it all the worst features of both telnet and e-mail.</p>
<p>The server&#8217;s primary method of extensibility would require spawning external processes, thus ensuring both security risks and unpredictable load.</p>
<p>The server would have no built-in mechanism for gracefully apportioning resources, refusing or delaying heavy traffic, or load-balancing. It would, however, be relatively easy to crash.</p>
<p>Multiple files traveling together from one server to one client would each incur the entire overhead of a new session call.</p>
<p>The hypertext model would ignore all serious theoretical work on hypertext to date. In particular, all hypertext links would be one-directional, thus making it impossible to move or delete a piece of data without ensuring that some unknown number of pointers around the world would silently fail.</p>
<p>The tag set would be absurdly polluted and user-extensible with no central coordination and no consistency in implementation. As a bonus, many elements would perform conflicting functions as logical and visual layout elements.</p>
<p>HTTP and HTML are the Whoopee Cushion and Joy Buzzer of Internet protocols, only comprehensible as elaborate practical jokes. For anyone who has tried to accomplish anything serious on the Web, it&#8217;s pretty obvious that of the various implementations of a worldwide hypertext protocol, we have the worst one possible.</p>
<p>Except, of course, for all the others.</p>
<p>The problem with that list of deficiencies is that it is also a list of necessities &#8212; the Web has flourished in a way that no other networking protocol has except e-mail, not despite many of these qualities but because of them. The very weaknesses that make the Web so infuriating to serious practitioners also make it possible in the first place. In fact, had the Web been a strong and well-designed entity from its inception, it would have gone nowhere. As it enters its adolescence, showing both flashes of maturity and infuriating unreliability, it is worth recalling what the network was like before the Web.</p></blockquote>
<p>My thoughts about a RESTful design in Symfony need to be qualified: I&#8217;m mostly talking about architecture for robot-consumed APIs. The architecture I&#8217;m thinking of is not necessarily one that you would need to adopt for a site that is meant for humans. Richardson and Ruby make a distinction between the &#8220;human web&#8221; and the &#8220;programmable web&#8221;, that is, sites that are meant to be seen by humans, versus sites that are mostly devoured by software robots that need to consume data to fulfil whatever function they&#8217;ve been programmed to do. From page 1:</p>
<blockquote><p>When you &#8211; a human being &#8211; want to find a book on a certain topic, you probably point your web browser to the URI of an online bookstore: say, http://www.amazon.com/</p>
<p>You&#8217;re served a web page, a document in HTML format that your browser renders graphically. You visually scan the page for a search form, type your topic (say, &#8220;web services&#8221;)  into a text box, and submit the form. At this point your web browser makes a second HTTP request, to a URI that incorporates your topic&#8230;</p>
<p>The web server at amazon.com responds by serving a second document in HTML format. This document contains a description of your search results, links to additional search options, and miscellaneous commercial enticements. Again, your browser renders the document in graphical form, and you look at it and decide what to do from there. </p>
<p>The web you use is full of data: book information, opinions, prices, arrival times, messages, photographs, and miscellaneous junk. It&#8217;s full of services: search engines, online stores, weblogs, wikis, calculators and games. Rather than installing all this data and all these programs on your own computer, you install one program &#8211; a web browser &#8211; and access the data and services through it. </p>
<p>The programmable web is just the same. The main difference is that instead of arranging its data in attractive HTML pages with banner ads and cute pastel logos, the programmable web usually serves stark, brutal XML documents. The programmable web is not necessarily for human consumption. Its data is intended as input to a software program that does something amazing. </p></blockquote>
<p>On most of the Symfony projects that I&#8217;ve worked on so far, the tendency has been to have one module for one model. There have been some variations on that theme, but that has been the trend. For instance, to handle the users of a site, we might have a database table called sf_guard_user_profile, and then a model called sfGuardUserProfile, and a module called &#8220;user&#8221;, and in that module we might put every action that has anything to do with the model &#8211; look at all users, look at frequent users, look at a particular user, send a message to a user, update the user, show the user&#8217;s dashboard, show the user&#8217;s finances. On the <a href="http://www.mybailiwick.com/">MyBailiwick</a> project we had huge modules &#8211; the user module had 40 public functions and maybe a dozen protected or private ones. </p>
<p>Building a RESTful API calls for a different design. Following the advice or Richardson and Ruby, we might end up with lots of very small modules, each of which have only 4 or 5 functions, corresponding to these actions: </p>
<p>read all (list all of a type)</p>
<p>read one (show one of a type)</p>
<p>write (create)</p>
<p>update </p>
<p>delete</p>
<p>Richardson and Ruby feel strongly that the method name (the action to be undertaken) should be one of the HTTP verbs:</p>
<p>GET</p>
<p>POST</p>
<p>PUT</p>
<p>DELETE</p>
<p>This is what Richardson and Ruby refer to as the &#8220;uniform interface&#8221; of HTTP. Unlike the ever changing, and confusing, interface of protocols such as SOAP or WSDL, HTTP has a simple interface, made up of 7 verbs, and the interface is not likely to change. </p>
<p>In a well-designed RESTful architecture, the method action does not go in the URL, it goes in the HTTP headers. In the course of the book, Richardson and Ruby set out to create an API for a site that allows people to upload and create their own maps. Here they talk about creating the service that will allow the site to create new user accounts (from page 149): </p>
<blockquote><p>Expose a subset of the uniform interface</p>
<p>This is the first new step. I skipped it when designing read-only resources, because there was nothing to decide. By definition, read-only resources are the ones that expose no more than the HTTP methods GET, HEAD and OPTIONS. Now that I&#8217;m designing resources that can be created and modified at runtime, I also have PUT, POST and DELETE to consider. </p>
<p>Even so, this step is pretty simple because the uniform interface is always the same. If you find yourself wishing there were more HTTP methods, the first thing to do is go back to step two, and try to split up your data set so you have more kinds of resources. Only if this fails should you consider introducing an element of the RPC style by making a particular resource support overloaded POST. </p>
<p>To reiterate the example from Chapter 5: if you have resources for &#8220;readers&#8221;, and resources for &#8220;published columns,&#8221; and you start thinking &#8220;it sure would be nice if there was a SUBSCRIBE method in HTTP,&#8221; the best thing to do is to create a new kind of resource: the &#8220;subscription&#8221;.  As HTTP resources, subscriptions are subject to HTTP&#8217;s uniform interface. If you decide to forgo the uniform interface and handle subscriptions through overloaded POST on your &#8220;reader&#8221; resources, defining the interface for those resources becomes much more difficult. </p>
<p>I can decided which bits of the uniform interface to expose by asking questions about intended usage:</p>
<p>1.) Will clients be creating new resources of this type? Of course they will. There&#8217;s no other way for users to get on the system. </p>
<p>2.) When the client creates a new resource of this type, who&#8217;s in charge of determining the new resource&#8217;s URI? Is it the client or the server? The client is in charge, since the URI is made up entirely of constant strings (https://maps.example.com/user/) and variables under the client&#8217;s control ({user-name}).</p>
<p>From those two questions I get my first result. To create a user account, a client will send a PUT request to the account&#8217;s URI. If the answer to the second question was &#8220;the server&#8217;s in charge of the final URI,&#8221; I&#8217;d expect my clients to create a user by sending a POST request to some &#8220;factory&#8221; or &#8220;parent&#8221;  URI.</p></blockquote>
<p>Again, this advice is aimed at API&#8217;s that are designed to be consumed by computers, not humans. But I like the idea of designing my code so that it could function, without much change, for dual use, as both an architecture for a human readable website, and also for an API for computers. This style of architecture would be a big change for me. Right now I&#8217;m working to refactor the code on <a href="http://www.wpquestions.com/">WP Questions</a>. As I look through the modules, I see that many of them could be broken apart into smaller modules, each with just 4 or 5 public functions: read, write, update delete. Though I worry about ending up with too many modules, I like the idea of each module being simple and focused. And RESTful. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=yktQR10rcJI:YVEXpqhjXwM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=yktQR10rcJI:YVEXpqhjXwM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=yktQR10rcJI:YVEXpqhjXwM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=yktQR10rcJI:YVEXpqhjXwM:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/yktQR10rcJI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=339</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=339</feedburner:origLink></item>
		<item>
		<title>Netbeans is a good IDE for Symfony development</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/NNoInPhPycw/</link>
		<comments>http://symfonynerds.com/blog/?p=337#comments</comments>
		<pubDate>Thu, 07 Jan 2010 00:38:30 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[tip]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[netbeans]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=337</guid>
		<description><![CDATA[I agree with this: Netbeans is a good IDE for Symfony development. I think this is especially true if you, like me, also develop with JVM languages. This last year I was doing some Java/Swing and Groovy projects, so I started using NetBeans again. It has a plugin for doing Symfony work &#8211; very handy. [...]]]></description>
			<content:encoded><![CDATA[<p>I agree with this: <a href="http://www.fractalizer.ru/frpost_393/free-opensource-symfony-friendly-ide-netbeans-6-8/">Netbeans is a good IDE for Symfony development</a>. I think this is especially true if you, like me, also develop with JVM languages. This last year I was doing some Java/Swing and Groovy projects, so I started using NetBeans again. It has a plugin for doing Symfony work &#8211; very handy.</p>
<p>(Off topic, the more I work with Groovy, the more I think this is <a href="http://www.teamlalala.com/blog/2010/01/02/groovy-is-an-easy-step-into-the-jvm-world-for-php-developers/">the perfect language for PHP developers who want to learn a JVM language</a>.)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=NNoInPhPycw:-vU3fecnjdc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=NNoInPhPycw:-vU3fecnjdc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=NNoInPhPycw:-vU3fecnjdc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=NNoInPhPycw:-vU3fecnjdc:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/NNoInPhPycw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=337</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=337</feedburner:origLink></item>
		<item>
		<title>Worker classes in Symfony</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/n98ySP1p98k/</link>
		<comments>http://symfonynerds.com/blog/?p=335#comments</comments>
		<pubDate>Tue, 22 Dec 2009 19:53:54 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[General Symfony]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=335</guid>
		<description><![CDATA[I&#8217;ve been thinking about the fact that the engineers at Google view static classes as terrible things. My own code has an unfortunate number of static classes. Mostly this is because I am not sure where to put some of the code. For instance, on every project I have a few methods that format output. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking about the fact that <a href="http://symfonynerds.com/blog/?p=293">the engineers at Google view static classes as terrible things</a>. My own code has an unfortunate number of static classes. Mostly this is because I am not sure where to put some of the code. For instance, on every project I have a few methods that format output. Some of these methods are the same on every project, so I hate to put them in the action code. Where else? Output formatting obviously does not belong in the model classes. What about methods for formatting dates, methods which I use in action code in multiple modules? It is easiest to put this into a class of static methods. Then I can call it from everywhere. </p>
<p>Another approach would be to add methods to the parent class. The parent of all action classes is sfActions. I&#8217;ve thought about editing sfActions, but I hate the idea of editing a core class of Symfony. I&#8217;ve also thought about creating a child class of sfActions, adding my methods there, and then having all of my action classes inherit from that. This is probably the best way to go, but I admit to a certain laziness. At some point I plan to write my own custom generation classes, which would make this easier. For now I tend to rely on the auto-generate code. Also, there are some good arguments against tall object trees. In his book <a href="http://www.amazon.com/Effective-Java-Programming-Language-Guide/dp/0201310058">Effective Java</a>, Joshua Bloch suggests &#8220;Favor composition over inheritance.&#8221;</p>
<p>Given these concerns, I was interested to read <a href="http://dev.esl.eu/blog/2009/06/10/worker-classes-in-symfony-part-1/">this article about worker classes in Symfony</a>. They list these advantages: </p>
<blockquote><p>Advantages of worker classes</p>
<p>   1. actions could be shrinked huge in size</p>
<p>   2. worker classes are more decoupled from the rest of symfony and could be tested better</p>
<p>   3. you can replace the content of an worker method without breaking actions</p></blockquote>
<p>This is a step away from the problems of static classes. It provides a place in the object hierarchy where this code might legitimately belong. The engineers at Google suggested that most static methods should really belong to one of their own parameters. I can imagine worker classes as a way of making this happening, without bloating up the owning class.</p>
<p><a href="http://dev.esl.eu/blog/2009/06/11/worker-classes-in-symfony-part-2/">A follow-up article looks at the interface changes that worker classes allow</a>. These changes should allow better long-term maintainability and better testing. I especially like the idea of removing all ORM specific code from my action classes. </p>
<blockquote><p>The action (or template) does not process anymore with a concrete ORM model. With the help of the proxy class, we can change the underlying model layer without breaking anything in the action. By providing a well defined interface, the proxy class manages how a model could be modified and accessed.</p>
<p>At this point, you should understand the reason for all those changes. It may look like a huge overhead for just retrieving some data out of the model. But in our case it was a precondition for our global architecture.</p>
<p>Our models and our main business logic is partly served by and processed in SOA applications (there we use Propel and i hope in some near days also Doctrine). I implemented a mechanism, which allows worker classes to access those SOA applications very easily. They are fetching the serialized data from those applications, hydrate them into proxy classes and provide them to the rest of the project.</p>
<p>&#8230;In this way, action code is really short, it is completely decoupled from the logic how the model is originally handled and it works quite well. If we decide to change something in our architecture some day, we only have to change our worker and proxy classes. The rest of the project will not notice those changes, as it should be in a layered architecture.</p>
<p>Sure, this step is nothing for small applications. But when your project grows and grows, the number of requests in a second turns from dozens to hundreds, then you’ll be thankful, if your project provides this approach.</p></blockquote>
<p>I will probably be adopting some of this technique for <a href="http://www.wpquestions.com/">my own current project</a>. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=n98ySP1p98k:0C1jT78BN2Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=n98ySP1p98k:0C1jT78BN2Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=n98ySP1p98k:0C1jT78BN2Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=n98ySP1p98k:0C1jT78BN2Y:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/n98ySP1p98k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=335</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=335</feedburner:origLink></item>
		<item>
		<title>A new website, and some thoughts on choosing Symfony</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/odd4zW9Rq24/</link>
		<comments>http://symfonynerds.com/blog/?p=323#comments</comments>
		<pubDate>Wed, 09 Dec 2009 09:33:56 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[Symfony MVC]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=323</guid>
		<description><![CDATA[Darren Hoyt and I rolled out a new website yesterday. WP Questions is a place for WordPress developers to go when they have questions so urgent that they are willing to pay money to get an answer. We built the site using Symfony, and I&#8217;d like to use this site to talk about the situations [...]]]></description>
			<content:encoded><![CDATA[<p>Darren Hoyt and I rolled out a new website yesterday. <a href="http://wpquestions.com/">WP Questions</a> is a place for WordPress developers to go when they have questions so urgent that they are willing to pay money to get an answer. We built the site using Symfony, and I&#8217;d like to use this site to talk about the situations where I think Symfony makes a great choice as a development platform. </p>
<p>First, understand our goals. We needed to create a site that allowed questions to be posted, money to be taken, answers to be given, and money dispersed to the person who had offered the most useful answer. <a href="http://blog.wpquestions.com/2009/12/07/introducing-wpquestions/">Darren Hoyt did a good job of summarizing the goals of the site</a>.</p>
<p>Right now we are listening to feedback and fine-tuning the site. Once we feel we have fixed all the bugs and added all the needed features, we plan to roll out an identical site for each of the major technologies: Java, Ruby, Rails, Symfony, Cake, Drupal, .NET Oracle, SQL, Javascript, etc. </p>
<p>So what do we need in our development platform?</p>
<p>1.) We can not guess the future of our data storage so we need database abstraction that keeps SQL out of our code. </p>
<p>2.) We know the structure of our data will evolve, so we need an ORM that can mask the changes.</p>
<p>3.) We know the designs will evolve and multiply even as the data schema evolves, so we need a clean MVC architecture that allows us to correctly observe a separation of concerns.</p>
<p>4.) We know that if we are successful we will eventually need to hire other programmers, so we need a well-documented framework that other programmers know, preferably one that is open source. </p>
<p>5.) We need to maintain the code base even as we scale up to running 100 sites, so we need a framework that allows us to run 100 sites off a single installation. </p>
<p>So what should we use? </p>
<p><a href="http://www.wptavern.com/forum/business-thinktank/781-problem-solving-contest-site-wordpress-4.html">A few months ago it was suggested that we use WordPress to develop the site</a>. I think this is clearly a bad idea. WordPress has a fairly rigid database structure. A developer can add new database tables to any WordPress installations, but establishing relationships between the new tables and the core tables is always a bit of a hack. And WordPress engages in some practices that I regard as extremely questionable, such as storing config data in the database and using fields in the database to store formatted text that needs to be drawn out and parsed for data &#8211; data storage inside of data storage. </p>
<p>We could have also started with forum software like <a href="http://www.phpbb.com/">phpBB</a> and then hacked it to add in the other features that we wanted. But again, it would be an uphill struggle against a database structure that makes too many assumptions about what we need, and which offers us few tools to evolve the structure over time. And, personally, I find their template system a pain to edit. </p>
<p><a href="http://symfonynerds.com/blog/?p=301">Last month I complained about the prominence of Drupal</a>. The comments in that thread show that Drupal has some very strong supporters. However, Drupal started life as a CMS, and still shows some traces of that, in terms of assumptions about database structure. Also, its files live within the directory of the server that is made available to the public on the web, something I regard as a security risk. Karl made a good point in a comment in that thread: </p>
<blockquote><p>Interesting here is that I looked at drupal, but choose not to use it, instead, Symfony was the choice. The two biggest reasons was 3rd party integration with quickbooks and scalability, we were afraid that drupals datamodel would cause us headaches at the end.</p></blockquote>
<p>I like the way that James Herrmann summed things up at the end: </p>
<blockquote><p>What are the questions asked that lead to the answer of ‘Symfony’, ‘Cake’, or ‘Solar’? I have a feeling they would entail infinite extensibility, unit testing, bridging with other libraries, optimization and security, to name a few.</p></blockquote>
<p>Clearly, using a CMS is a bad idea when you know you&#8217;ll need a maximum of flexibility in the future. But why use Symfony? Why not use one of the other frameworks? <a href="http://www.grails.org/">Grails</a> offers a clean architecture, a great plugin system, a highly productive dynamic environment. Groovy, and the JVM, is somewhat faster than PHP, so it offers a speed boost which might be important when we need to scale up. I&#8217;ve written enough Groovy code that I could probably write the app in Grails if I wanted to. So why not? My reasons here have to do with the overall eco-systems that surround the 2 languages. There is an abundant supply of PHP programmers. More importantly, the sysadmins I know are comfortable with Linux, Apache and PHP, but not with Tomcat. In the bad old days, the whole world of Java was geared toward Fortune 500 companies with big budgets. The frameworks were as verbose as the underlying language. The idea of dynamic languages and lightweight frameworks is relatively new to the world of the JVM. PHP, by contrast, has been stable for 10 years now, and it has a huge following. </p>
<p>There are, of course, a hundred other technologies I might have considered, but I am limited to the ones I know well. </p>
<p>Symfony is going to allow us to grow and evolve the database structure while keeping the code clean. I&#8217;ll give you an example. On our <a href="http://www.wpquestions.com/user/winners/order/desc/">Top Winners</a> page we offer a few ways of sorting. The page shows the users, their name, their image and how much they&#8217;ve won. I must draw the data out of these 2 tables: </p>
<blockquote><p>sf_guard_user_profile:<br />
    _attributes: { phpName: sfGuardUserProfile }<br />
    id:               ~<br />
    user_id:          { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: true }<br />
    status:           { type: varchar(255), required: false }<br />
    first_name:       { type: varchar(255), required: false }<br />
    last_name:        { type: varchar(255), required: false }<br />
    email:            { type: varchar(255), required: false }<br />
    url:              { type: varchar(255), required: false }<br />
    biography:        { type: longvarchar, required: false }<br />
    created_at:       ~<br />
    updated_at:        ~<br />
    cash_total:       { type: float, required: false }<br />
    image:            { type: VARCHAR, size:255 }<br />
    secret_signup_key: { type: VARCHAR, size:255 }</p>
<p>answer:<br />
    id:                 ~<br />
    user_id:            { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: false }<br />
    question_id:        { type: integer, foreignTable: question, foreignReference: id, required: false  }<br />
    image:              { type: varchar(255), required: false }<br />
    description:        { type: longvarchar, required: false  }<br />
    status:             { type: varchar(255), required: false }<br />
    score:              { type: integer, required: false }<br />
    prize_amount_paid_for_this_answer:       { type: float, required: false }<br />
    created_at:         ~<br />
    updated_at:         ~</p></blockquote>
<p>I need to create a JOIN. There is no foreign key relationships between these 2 tables, so the automatically generated Propel classes do not have any JOIN methods. I prefer to handle this by creating a database view, </p>
<blockquote><p>CREATE VIEW answers_totals_users AS<br />
    SELECT answer.*,<br />
    COUNT(question_id) as questionTotal,<br />
    SUM(prize_amount_paid_for_this_answer) as prizeTotal,<br />
    sf_guard_user_profile.first_name, sf_guard_user_profile.last_name,<br />
    sf_guard_user_profile.image AS userImage<br />
    FROM answer, sf_guard_user_profile<br />
    WHERE answer.user_id=sf_guard_user_profile.user_id<br />
    GROUP BY answer.user_id</p></blockquote>
<p>and then I add it to schema.yml as if it was a real database table: </p>
<blockquote><p>answers_totals_users:<br />
    id:                 ~<br />
    user_id:            { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: false }<br />
    question_id:        { type: integer, foreignTable: question, foreignReference: id, required: false  }<br />
    image:              { type: varchar(255), required: false }<br />
    description:        { type: longvarchar, required: false  }<br />
    status:             { type: varchar(255), required: false }<br />
    score:              { type: integer, required: false }<br />
    prize_amount_paid_for_this_answer:       { type: float, required: false }<br />
    prizeTotal:       { type: float, required: false }<br />
    questionTotal:    { type: integer, required: false }<br />
    created_at:         ~<br />
    updated_at:         ~<br />
    first_name:       { type: varchar(255), required: false }<br />
    last_name:        { type: varchar(255), required: false }<br />
    userImage:            { type: VARCHAR, size:255 }</p></blockquote>
<p>Then I run the &#8220;symfony propel:build-model&#8221; command, and now I have a model class that selects against this JOIN as if it was a single table. This leaves my action code looking simple and clean: </p>
<blockquote><p>$limit = $request-&gt;getParameter(&#8216;limit&#8217;);<br />
   if (!$limit) $limit = 25;<br />
   $c = new Criteria();<br />
   $c-&gt;setLimit($limit);<br />
   $c-&gt;add(AnswersTotalsUsersPeer::PRIZETOTAL, 0, Criteria::GREATER_THAN);<br />
   $c-&gt;addDescendingOrderByColumn(AnswersTotalsUsersPeer::PRIZETOTAL);<br />
   $this-&gt;listOfTopWinners = AnswersTotalsUsersPeer::doSelect($c); </p></blockquote>
<p><a href="http://blog.wpquestions.com/2009/11/26/history-incubation-and-inspirations/">I started to think of a site such as this one some years ago, when I first used Experts Exchange</a>. I was frustrated that Experts Exchange took my money, yet none of the money went to the people who were helping me. I wanted a site where I could give money directly to the people answering my questions. My ideas about this site have become more clear over time, and no doubt 6 months from now I&#8217;ll have even more clarity about how this site/software can be useful to people. Likewise, as we get more feedback from our users we will continue to add new features, and offer more information. They&#8217;ll be a need for more JOINs and sometimes new database tables. A framework like Symfony assumes a changing database structure, it is set up to help a developer deal with those changes, and in this it is different from the CMSs that assume they know what kind of site you are building. Symfony, therefore, offers an attractive set of features for developing our site/software over the long term. It is the ideal development platform for us. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=odd4zW9Rq24:SxEh8c3lHJo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=odd4zW9Rq24:SxEh8c3lHJo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=odd4zW9Rq24:SxEh8c3lHJo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=odd4zW9Rq24:SxEh8c3lHJo:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/odd4zW9Rq24" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=323</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=323</feedburner:origLink></item>
		<item>
		<title>Symfony Quick Tip: Forward vs Redirect</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/lkMAsg-knDs/</link>
		<comments>http://symfonynerds.com/blog/?p=319#comments</comments>
		<pubDate>Fri, 04 Dec 2009 03:08:51 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[1.2]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=319</guid>
		<description><![CDATA[This tip is a quick one for newbies. The Symfony book has some great tips as to when you would want to use a Symfony forward, vs a Symfony redirect. This quick post will show you the difference between the two and give you some guidelines to know when to use redirect or forward. So [...]]]></description>
			<content:encoded><![CDATA[<p>This tip is a quick one for newbies. The Symfony book has some <a href="http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer#chapter_06_sub_skipping_to_another_action">great tips</a> as to when you would want to use a Symfony forward, vs a Symfony redirect. This quick post will show you the difference between the two and give you some guidelines to know when to use redirect or forward.</p>
<p><strong>So what&#8217;s the main difference?</strong></p>
<p><strong>Symfony Redirect:</strong> This simply does a HTTP header(”location: “)<strong><br />
Symfony Forward: </strong>This is complete custom code that comes with the Symfony framework that forwards you within the Symfony application.</p>
<p>Use Symfony Forward if:</p>
<ul>
<li>If the action needs to forward a call to another action<br />
This will mean you can keep all the action class&#8217; objects in scope and still have access to them</li>
<li>You want to forward the user to an action within the application, and keep it transparent to the user.<br />
From a users perspective &#8211; the displayed URL stays the same.</li>
</ul>
<p>Use a Symfony Redirect if:</p>
<ul>
<li>You need to go to an external website (http://google.com for example)</li>
<li>You don&#8217;t want the user to re-submit a form (if you are doing a form POST)<br />
It is generally good practice to do a redirect after a POST to ensure the user does not re-submit the form.</li>
</ul>
<p><strong>Conditional Forwarding/redirect</strong><br />
Quite often you need to forward or redirect if a condition has been met. Be sure to checkout the other Symfony functions that help you do this (forwardIf(), forwardUnless(), forward404If(), forward404Unless(), redirectIf(), and redirectUnless())</p>
<p><strong>What about AJAX calls?<br />
</strong>You can check if a HTTP request is an AJAX call before deciding what to do with it by calling calling  $request-&gt;isXmlHttpRequest() in your actions class. Once you have done this you can choose what you want to do; redirect or forward.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=lkMAsg-knDs:l_4LQF1zvio:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=lkMAsg-knDs:l_4LQF1zvio:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=lkMAsg-knDs:l_4LQF1zvio:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=lkMAsg-knDs:l_4LQF1zvio:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/lkMAsg-knDs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=319</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=319</feedburner:origLink></item>
		<item>
		<title>Are you in New York City?</title>
		<link>http://feedproxy.google.com/~r/symfony/~3/MaPcAm8BAII/</link>
		<comments>http://symfonynerds.com/blog/?p=314#comments</comments>
		<pubDate>Fri, 04 Dec 2009 01:46:30 +0000</pubDate>
		<dc:creator />
				<category><![CDATA[community]]></category>

		<guid isPermaLink="false">http://symfonynerds.com/blog/?p=314</guid>
		<description><![CDATA[I’m gathering together some web and tech and design people to go out for drinks on December 9th. Give me a shout if you are in New York City and would like an invite. Be sure to include your website or Twitter address, which I&#8217;ll pass along to all other invitees. Contact me at: la [...]]]></description>
			<content:encoded><![CDATA[<p>I’m gathering together some web and tech and design people to go out for drinks on December 9th. Give me a shout if you are in New York City and would like an invite. Be sure to include your website or Twitter address, which I&#8217;ll pass along to all other invitees. </p>
<p>Contact me at:   la   @   teamlalala.com</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/symfony?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/symfony?i=MaPcAm8BAII:iUza3khY3A8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/symfony?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/symfony?i=MaPcAm8BAII:iUza3khY3A8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/symfony?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/symfony?i=MaPcAm8BAII:iUza3khY3A8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/symfony?a=MaPcAm8BAII:iUza3khY3A8:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/symfony?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/symfony/~4/MaPcAm8BAII" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://symfonynerds.com/blog/?feed=rss2&amp;p=314</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://symfonynerds.com/blog/?p=314</feedburner:origLink></item>
	</channel>
</rss>

