<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://townx.org" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>townx - I Hear a Symfony: Rails vs. the Symfony PHP framework - Comments</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework</link>
 <description>Comments for &quot;I Hear a Symfony: Rails vs. the Symfony PHP framework&quot;</description>
 <language>en</language>
<item>
 <title>This Drupal site is on</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-38630</link>
 <description>&lt;p&gt;This Drupal site is on shared hosting. I wouldn&#039;t use any other blogging system. Wordpress would have been my suggestion, but sounds like you&#039;ve already decided you don&#039;t like it much.&lt;/p&gt;</description>
 <pubDate>Wed, 10 Dec 2008 14:34:17 -0600</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 38630 at http://townx.org</guid>
</item>
<item>
 <title>I am just a blogger and</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-38629</link>
 <description>&lt;p&gt;I am just a blogger and nothing else so I am not in that all technical programming language so just goign to ask a very simple thing. I am tired of wordpress upgrades so moved to Drupal. I started loving it but my host don&#039;t. They refrain me to use it because i was on a shared host. Now IO am looking for another blogging system which should work like Drupal. So is it somethign similar to that? I am talking about Symphony. &lt;/p&gt;</description>
 <pubDate>Wed, 10 Dec 2008 00:01:25 -0600</pubDate>
 <dc:creator>Leonardo Medina</dc:creator>
 <guid isPermaLink="false">comment 38629 at http://townx.org</guid>
</item>
<item>
 <title>Hi Ben. I&#039;m not aware of any</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14489</link>
 <description>&lt;p&gt;Hi Ben. I&#039;m not aware of any &lt;span class=&quot;caps&quot;&gt;CMS&lt;/span&gt;s written with Symfony. I&#039;d go for Drupal under any circumstances :)&lt;/p&gt;</description>
 <pubDate>Thu, 01 Nov 2007 15:17:20 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14489 at http://townx.org</guid>
</item>
<item>
 <title>What CMS&#039;s run well on Symfony?</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14461</link>
 <description>&lt;p&gt;We&#039;re strongly considering moving to Symfony from our own &lt;span class=&quot;caps&quot;&gt;CMS &lt;/span&gt;system which we built using &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;with Smarty templating.  We need to find the best, most flexible, most powerful &lt;span class=&quot;caps&quot;&gt;CMS &lt;/span&gt;available if we go in this direction.  Can you recommend any particular &lt;span class=&quot;caps&quot;&gt;CMS &lt;/span&gt;for use within Symfony?&lt;/p&gt;</description>
 <pubDate>Wed, 17 Oct 2007 12:24:10 -0500</pubDate>
 <dc:creator>Ben Fajen</dc:creator>
 <guid isPermaLink="false">comment 14461 at http://townx.org</guid>
</item>
<item>
 <title>Thanks for letting me know</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14302</link>
 <description>&lt;p&gt;Thanks for letting me know about that. I too have had issues with Propel, as it seems pretty clumsy and inflexible in places. I will mention Doctrine in the article and have a look myself.&lt;/p&gt;</description>
 <pubDate>Tue, 14 Aug 2007 05:30:45 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14302 at http://townx.org</guid>
</item>
<item>
 <title>About the Symfony framework</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14300</link>
 <description>&lt;p&gt;Hey, glad to see the symfony web sphere is getting bigger and bigger. As a symfony user/developper since two years now, i&#039;m happy to see how it&#039;s used by more and more people. But maybe you could point out that Propel is not the only &lt;span class=&quot;caps&quot;&gt;O.R.M &lt;/span&gt;available for symfony, an under-development &lt;span class=&quot;caps&quot;&gt;ORM &lt;/span&gt;called &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;-Doctrine is increasing stability every day, and as the #doctrine channels topic clams, &quot;RC 1 to be released at 31st of August&quot;. Doctrine is far mor contraining than Propel, as it does not generates static methods but insteads allows you to make complex arbitrary joins in your schema following the &lt;span class=&quot;caps&quot;&gt;DQL &lt;/span&gt;(Doctrine Query Language). I worked for one year with propel, and headaches came so fast i had to find a solution. Even is doctrine is not yet 100% ready for production use, it will be soon, and i personnaly use it in production on some small sites already.&lt;/p&gt;

&lt;p&gt;Keep spreading the word :-)&lt;/p&gt;</description>
 <pubDate>Mon, 13 Aug 2007 12:20:36 -0500</pubDate>
 <dc:creator>hartym</dc:creator>
 <guid isPermaLink="false">comment 14300 at http://townx.org</guid>
</item>
<item>
 <title>Cheers, glad it was useful</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14299</link>
 <description>&lt;p&gt;Cheers, glad it was useful and thanks for taking the time to comment.&lt;/p&gt;</description>
 <pubDate>Mon, 13 Aug 2007 10:37:27 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14299 at http://townx.org</guid>
</item>
<item>
 <title>Nice one! Glad you found it</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14298</link>
 <description>&lt;p&gt;Nice one! Glad you found it interesting.&lt;/p&gt;</description>
 <pubDate>Mon, 13 Aug 2007 10:35:26 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14298 at http://townx.org</guid>
</item>
<item>
 <title>Propel queries</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14296</link>
 <description>&lt;p&gt;This was a great article! In case anyone was following along, I believe you could reduce your retrieval function even more and use the &quot;doSelectOne&quot; method available in your base peer classes:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
public static function retrieveByTitle($title) {
  $c = new Criteria();
  $c-&amp;gt;add(self::TITLE, $title);
  return self::doSelectOne($c);
}
&lt;/code&gt;&lt;/pre&gt;</description>
 <pubDate>Sat, 11 Aug 2007 12:09:56 -0500</pubDate>
 <dc:creator>Scott Meves</dc:creator>
 <guid isPermaLink="false">comment 14296 at http://townx.org</guid>
</item>
<item>
 <title>Fantastic, thnx...!</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14294</link>
 <description>&lt;p&gt;Thank you very much for &quot;getting your hands dirty&quot; and sharing your expiriences with symfony. Such a review from someone who has actually coded something is much more valuable than all those comparisons that only show information gathered from different websites.&lt;/p&gt;</description>
 <pubDate>Sat, 11 Aug 2007 03:28:37 -0500</pubDate>
 <dc:creator>Skaldrom Y. Sarg</dc:creator>
 <guid isPermaLink="false">comment 14294 at http://townx.org</guid>
</item>
<item>
 <title>Thanks for commenting. I</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14249</link>
 <description>&lt;p&gt;Thanks for commenting. I tend to agree: symfony is a bit big and complex, and I had a hard time getting my head round some of it (the Apress book is OK but not particularly task-oriented: it explains where everything is and what it&#039;s for, but not how to use it). I&#039;ve been working with Propel and Smarty this weekend, and have managed to put together a fairly lean and simple &lt;span class=&quot;caps&quot;&gt;MVC &lt;/span&gt;framework in about a day, with some quite Rails-like features but without the complexity of symfony. I might have a go at building something with that, rather than symfony.&lt;/p&gt;</description>
 <pubDate>Sun, 08 Jul 2007 02:18:29 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14249 at http://townx.org</guid>
</item>
<item>
 <title>Thanks for the Great Post!</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14246</link>
 <description>&lt;p&gt;Great post. I was looking for a rake-like helper for &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;(Pake, as you mention) and decided to keep reading to hear what other tools Symphony offers. I initially considered using Symphony to build my latest web app but decided against it for performance reasons. I think it&#039;s most sensible (for both pragmatic and performant development) to use a &quot;best-of-breed&quot; composite framework, taking the best (hopefully decoupled) bits and pieces from existing solutions and using those where applicable, thus avoiding the standard framework bloat. Thanks again for the writeup!&lt;/p&gt;</description>
 <pubDate>Fri, 06 Jul 2007 11:27:46 -0500</pubDate>
 <dc:creator>Ed</dc:creator>
 <guid isPermaLink="false">comment 14246 at http://townx.org</guid>
</item>
<item>
 <title>Thanks Adrian. I think my</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14181</link>
 <description>&lt;p&gt;Thanks Adrian. I think my experience was similar to yours: nice, but more painful than Rails. Though I did wonder whether this was because I know Rails pretty well, and Symfony not at all, so maybe my existing experience was colouring my perceptions. I found the documentation OK as far as tutorials went, but the &lt;span class=&quot;caps&quot;&gt;API &lt;/span&gt;documentation a bit lacking in explanation.&lt;/p&gt;</description>
 <pubDate>Tue, 05 Jun 2007 03:22:38 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14181 at http://townx.org</guid>
</item>
<item>
 <title>2 cents.</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14179</link>
 <description>&lt;p&gt;Nice review. I&#039;ve been using Rails for several months, but as a new project had &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;as a requirement I adopted symfony for that. While it is a decent framework indeed, I still found it to be rather painful compared to Rails (and Ruby, that is). Several features are lacking, but more importantly the documentation is rather poor and, at times, not helpful at all. The community support is nowhere as good either. It was a good experience nevertheless, but I am very much looking forward to going back to Rails...&lt;/p&gt;</description>
 <pubDate>Sun, 03 Jun 2007 22:15:52 -0500</pubDate>
 <dc:creator>Adrian</dc:creator>
 <guid isPermaLink="false">comment 14179 at http://townx.org</guid>
</item>
<item>
 <title>Thanks Michael, that&#039;s a</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comment-14069</link>
 <description>&lt;p&gt;Thanks Michael, that&#039;s a nice compliment. I&#039;ll definitely be looking at Symfony again for my next &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;project. Thanks for the routing tip too.&lt;/p&gt;</description>
 <pubDate>Fri, 16 Mar 2007 16:48:48 -0500</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">comment 14069 at http://townx.org</guid>
</item>
<item>
 <title>I Hear a Symfony: Rails vs. the Symfony PHP framework</title>
 <link>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework</link>
 <description>&lt;p&gt;No Ruby Tuesday this week, as I&#039;ve not been Ruby programming. Instead, I&#039;ve been having a look at the &lt;a href=&quot;http://www.symfony-project.com/&quot;&gt;Symfony&lt;/a&gt; &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;framework, to see whether it shapes up to Rails. As I&#039;ve stated previously, Rails is a pain to run on dirt-cheap hosting (though options like &lt;a href=&quot;http://planetargon.com/&quot;&gt;Planet Argon&lt;/a&gt; are out there, cheap enough, but I haven&#039;t tried them yet); plus Ruby is another language to learn for the people I work with at &lt;a href=&quot;http://openadvantage.org/&quot;&gt;OpenAdvantage&lt;/a&gt;, and most of them have got enough to do running small businesses. I wondered whether Symfony is good enough to recommend as an alternative to Rails for programmers who already know &lt;span class=&quot;caps&quot;&gt;PHP.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In short: it is.&lt;/p&gt;

&lt;p&gt;It&#039;s not perfect, not as concise as Rails, and lacks many of the features. But using it is a damned sight easier than writing a &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;application from scratch. I&#039;m not going to do a thorough feature listing (see the &lt;a href=&quot;http://www.symfony-project.com/&quot;&gt;Symfony site&lt;/a&gt; for that). Instead, here are some of the notable things about it that improve the life of &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;programmers:&lt;/p&gt;


&lt;ul&gt;
&lt;li&gt;It bundles in the &lt;a href=&quot;http://propel.phpdb.org/trac/&quot;&gt;Propel&lt;/a&gt; Object Relational Mapping layer for &lt;span class=&quot;caps&quot;&gt;PHP.&lt;/span&gt; I&#039;d heard of this but not used it before. It feels similar to &quot;Torque&quot; for Java, and isn&#039;t as neat as ActiveRecord, mostly because &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;lacks some of the advanced meta-programming available in Ruby. This means you end up with getters and setters when you create classes which &quot;peer&quot; for your tables (not neat methods as in ActiveRecord). You also get four classes per table: a Base class, a BasePeer class, a class representing the table (inherits from Base) which you can append methods to, and a peer for the table (inherits from BasePeer) which you can also append methods to. Much more verbose than ActiveRecord. (&lt;strong&gt;Note:&lt;/strong&gt; hartym (see comments) mentions that &lt;a href=&quot;http://www.phpdoctrine.net/trac/&quot;&gt;Doctrine&lt;/a&gt; is also available as an alternative &lt;span class=&quot;caps&quot;&gt;ORM &lt;/span&gt;layer for use with symfony. Might be worth a peep.)&lt;/li&gt;
&lt;li&gt;It includes a build tool called &lt;a href=&quot;http://www.pake-project.com/&quot;&gt;Pake&lt;/a&gt;, which works in a similar way to Rake but for &lt;span class=&quot;caps&quot;&gt;PHP.&lt;/span&gt; This means there are scaffold and migration style tasks you can run.&lt;/li&gt;
&lt;li&gt;There are separate frontend and backend scaffolding tools. The backend stuff reminds me of Django or Streamlined.&lt;/li&gt;
&lt;li&gt;It has a built-in (simple) authentication system. However, the fact that someone has thought about authentication probably means it&#039;s easier to work into an application than it is in Rails.&lt;/li&gt;
&lt;li&gt;Internationalisation and localisation are supported out of the box.&lt;/li&gt;
&lt;li&gt;It has more of a sense of structuring applications than Rails does, perhaps closer to Django. This could mean I could more easily move chunks of functionality around between Symfony applications without having the awkward feeling Rails plugins give me.&lt;/li&gt;
&lt;li&gt;There are far more configuration files (YAML). It feels more like Struts to me than Rails: you can tweak settings at various levels of granularity (whole of Symfony, per application, or per module). This is good in one sense (for example, validation is carried out in config. files, rather than in model classes, which makes it easier to share validation code around or tailor it for different actions). On the other hand, you do get a splurge of files to manage.&lt;/li&gt;
&lt;li&gt;It&#039;s &lt;span class=&quot;caps&quot;&gt;PHP, &lt;/span&gt;so it will run on bog-standard web hosting, backed by any Propel-capable database (including MySQL).&lt;/li&gt;
&lt;li&gt;By default, it uses &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;ite for the database in the development environment. Configuration works in a similar way to ActiveRecord&#039;s and is straightforward.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;AJAX &lt;/span&gt;support is built-in (using Prototype and Scriptaculous), and it has the same concept of helpers as Rails. This means you can build interfaces in a similar way to Rails interfaces, and many of the methods have similar names.&lt;/li&gt;
&lt;li&gt;It is based around a model-view-controller architecture, with a front-controller, very similar to Rails.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Next, a few specifics and code samples to give an idea of how it works.&lt;/p&gt;

&lt;h2&gt;My specific experiences&lt;/h2&gt;

&lt;p&gt;I chose a wiki as the project to experiment with, and have spent about a day and a half coding in Symfony. The result (fancifully called &lt;em&gt;Flow My Thoughts, The Policeman Said&lt;/em&gt;) is an extremely simple wiki which supports camel-case links, [[]] links and Textile markup.&lt;/p&gt;

&lt;p&gt;For the wiki parsing part of it, I borrowed some code from the Drupal &lt;a href=&quot;http://drupal.org/project/freelinking&quot;&gt;freelinking&lt;/a&gt; module and from &lt;a href=&quot;http://jimandlissa.com/project/textilephp&quot;&gt;TextilePHP&lt;/a&gt;. Along the way I fixed TextilePHP so that it works properly with strict error reporting on (there were lots of references to unset variables and possibly non-existent array indexes which meant I got around 100 error messages the first time I ran it). This means I can write wiki links as well as mix in Textile markup (I am  a big fan of Textile). Don&#039;t you just love open source?&lt;/p&gt;

&lt;p&gt;For the main part of the project I started with the Symfony sandbox download, as this includes all the libraries for Symfony in a tarball. You can also install the dependencies with &lt;span class=&quot;caps&quot;&gt;PEAR, &lt;/span&gt;and would want to if using Symfony for several projects. I also went with &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;ite for experimenting with.&lt;/p&gt;

&lt;h3&gt;The model&lt;/h3&gt;

&lt;p&gt;First off you edit a schema.yml file with details of your data model. This works pretty well, and is a bit like writing a migration. You can either use the sensible Symfony defaults or work with the Propel syntax directly (e.g. if you want specific options or indexes set for fields). My model looks like this:&lt;/p&gt;



&lt;pre&gt;
propel:
  page:
    _attributes: { phpName: Page }
    id:
    title:       { type: varchar, size: 255, index: unique }
    content:     longvarchar
    created_at:
    updated_at:
&lt;/pre&gt;



&lt;p&gt;Nothing too unusual there. Also notice the &quot;magic&quot; Rails-style fields, &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;updated_at&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To build the model classes from your schema, you run:&lt;/p&gt;



&lt;pre&gt;
php symfony propel-build-all
&lt;/pre&gt;



&lt;p&gt;The symfony file is a Pake build script. The &lt;code&gt;propel-build-all&lt;/code&gt; task generates some &lt;span class=&quot;caps&quot;&gt;XML &lt;/span&gt;from your &lt;span class=&quot;caps&quot;&gt;YAML &lt;/span&gt;files, which gets converted into &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;classes representing your tables. In my case, I got four files: BasePage, BasePagePeer, Page, PagePeer. Then it generates some &lt;span class=&quot;caps&quot;&gt;SQL &lt;/span&gt;and builds your database. All very migration-like. However, there&#039;s no sense of &quot;up&quot; and &quot;down&quot; in Symfony, and it&#039;s probably hard to version the database schema incrementally, like you can in migrations.&lt;/p&gt;

&lt;p&gt;As I mentioned above, the &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;classes are chock-full of getter and setter methods. Far more wordy than ActiveRecord&#039;s default two-line class definitions, and a consequence of the lack of runtime class extension in &lt;span class=&quot;caps&quot;&gt;PHP.&lt;/span&gt; However, only the Base classes (in my case, BasePage and BasePagePeer) are regenerated when you recreate the model using Pake. This means you can add your extensions into the classes which inherit from the Base classes (i.e. Page and PagePeer).&lt;/p&gt;

&lt;h3&gt;Scaffolding&lt;/h3&gt;

&lt;p&gt;Symfony supports generation of a &lt;span class=&quot;caps&quot;&gt;CRUD &lt;/span&gt;interface (i.e. scaffolding) from the model too:&lt;/p&gt;



&lt;pre&gt;
php symfony propel-generate-crud frontend page Page
&lt;/pre&gt;



&lt;p&gt;This actually creates an application called &quot;frontend&quot; inside your app. directory. This is interesting, as it illustrates how Symfony applications can be structured into parent-child relationships, unlike Rails where it&#039;s pretty flat.&lt;/p&gt;

&lt;p&gt;You can get at your application in development mode by browsing to (e.g.) &lt;a href=&quot;http://localhost/frontend_dev.php/page&quot; title=&quot;http://localhost/frontend_dev.php/page&quot;&gt;http://localhost/frontend_dev.php/page&lt;/a&gt;. This will use the default views for the &lt;span class=&quot;caps&quot;&gt;CRUD &lt;/span&gt;interface.&lt;/p&gt;

&lt;p&gt;The scaffolding sits inside the frontend application, and can be used to selectively override the defaults for the application. I added some directories to my page module:&lt;/p&gt;



&lt;pre&gt;
apps
  frontend
    modules
      page
        actions
        lib
          helper
        templates
        validate
&lt;/pre&gt;



&lt;p&gt;Note here that I can either add helpers for the module, or I can place them under frontend &amp;gt; lib &amp;gt; helper to add them to the whole application. This mirrors the distinction between application level and controller specific helpers in Rails, but is reflected by the directory structure, rather than by file naming. This seems unnecessarily complex, particularly if you&#039;re used to Rails. The other directories are fairly obvious, hopefully.&lt;/p&gt;

&lt;h3&gt;Routing&lt;/h3&gt;

&lt;p&gt;Routing is one area which had me foxed. I wanted to be able to use a &lt;span class=&quot;caps&quot;&gt;URL &lt;/span&gt;like this:&lt;/p&gt;



&lt;pre&gt;
&lt;a href=&quot;http://localhost/wiki/page/NameOfMyPage&quot; title=&quot;http://localhost/wiki/page/NameOfMyPage&quot;&gt;http://localhost/wiki/page/NameOfMyPage&lt;/a&gt;
&lt;/pre&gt;



&lt;p&gt;to be able to navigate to the page with the title NameOfMyPage. However, I couldn&#039;t for the life of me get this to work. In the end I had to settle for:&lt;/p&gt;



&lt;pre&gt;
&lt;a href=&quot;http://localhost/wiki/page/show/title/NameOfMyPage&quot; title=&quot;http://localhost/wiki/page/show/title/NameOfMyPage&quot;&gt;http://localhost/wiki/page/show/title/NameOfMyPage&lt;/a&gt;
&lt;/pre&gt;



&lt;p&gt;Note that the link_to helpers are a bit unwieldy compared to Rails, particularly as you don&#039;t have the luxury of symbols and automatic hashes from arguments like you do in Ruby:&lt;/p&gt;



&lt;pre&gt;
echo link_to($page_title, &#039;page/show?title=&#039;.$page-&amp;gt;getTitle());
&lt;/pre&gt;



&lt;p&gt;Even though this is only slightly more opaque and verbose than Rails, I think it would wear on me after a while.&lt;/p&gt;

&lt;h3&gt;Actions&lt;/h3&gt;

&lt;p&gt;The scaffold specifies the actions you&#039;d expect by default: for the page model, they ended up in apps/frontend/modules/page/actions/actions.class.php. Adding my own was simple enough. For example, I wanted to show a page by title. Showing a page by ID was supported by the scaffold already:&lt;/p&gt;



&lt;pre&gt;
public function executeShow() {
  $this-&amp;gt;page = PagePeer::retrieveByPk($this-&amp;gt;getRequestParameter(&#039;id&#039;));
  $this-&amp;gt;forward404Unless($this-&amp;gt;page);
}
&lt;/pre&gt;



&lt;p&gt;Mmmm, not quite as succinct as Rails, I was thinking. You can see the Torque-style (Propel) syntax for retrieving records in the first line of this method definition. Note that the template to render is implicit, and maps to apps/frontend/modules/page/templates/showSuccess.php.&lt;/p&gt;

&lt;p&gt;First, I added a new method to the PagePeer, to retrieve a record by title. This is located in lib/models/PagePeer.php, outside the application. The idea is you are likely to have multiple applications supporting a single model. On the other hand, it&#039;s probably possible to create models specific to individual applications (maybe even modules):&lt;/p&gt;



&lt;pre&gt;
public static function retrieveByTitle($title) {
  $c = new Criteria();
  $c-&amp;gt;add(self::TITLE, $title);
  return self::doSelectOne($c);
}
&lt;/pre&gt;



&lt;p&gt;The Criteria class used here is part of Propel, and it works pretty well (again, very Torque-like). Though again, more verbose than ActiveRecord. (Thanks to Scott Meves&#039; comment which cleaned up the above function.)&lt;/p&gt;

&lt;p&gt;Then I added an action to frontend/modules/page/actions/actions.class.php:&lt;/p&gt;



&lt;pre&gt;
public function executeShowByTitle() {
  $this-&amp;gt;page = PagePeer::retrieveByTitle($this-&amp;gt;getRequestParameter(&#039;title&#039;));
  $this-&amp;gt;forward404Unless($this-&amp;gt;page);
  $this-&amp;gt;setTemplate(&#039;show&#039;);
}
&lt;/pre&gt;



&lt;p&gt;Notice that this reuses the &#039;show&#039; template (setTemplate() specifies the one to use if different from the inferred template).&lt;/p&gt;

&lt;h3&gt;Helpers&lt;/h3&gt;

&lt;p&gt;I created my own helper to show error messages in apps/frontend/lib/helper/ErrorMessagesHelper.php:&lt;/p&gt;



&lt;pre&gt;
&amp;lt;?php
function error_on($field) {
  $error = sfContext::getInstance()-&amp;gt;getRequest()-&amp;gt;getError($field);
  $out = &#039;&#039;;
  if ($error) {
    $out = content_tag(&#039;div&#039;, $error, array(&#039;class&#039; =&amp;gt; &#039;error&#039;));
  }
  return $out;
}
?&amp;gt;
&lt;/pre&gt;



&lt;p&gt;Notice how I had to go round the houses to get at the error messages on the object. For some reason, error messages aren&#039;t stored on the object, but in the request. This makes them pretty hard to get at, and you have to use the Symfony context if you are not explicitly within a view. Also notice that there is a &lt;code&gt;content_tag&lt;/code&gt; helper.&lt;/p&gt;

&lt;p&gt;I can load this my helper into a template with:&lt;/p&gt;



&lt;pre&gt;
&amp;lt;?php use_helper(&#039;ErrorMessages&#039;) ?&amp;gt;
&lt;/pre&gt;



&lt;h3&gt;Templates&lt;/h3&gt;

&lt;p&gt;Nothing special here. Just &lt;span class=&quot;caps&quot;&gt;HTML &lt;/span&gt;with &lt;span class=&quot;caps&quot;&gt;PHP, &lt;/span&gt;plus some &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;helpers to make life a bit easier. For example, here&#039;s my edit form for pages:&lt;/p&gt;



&lt;pre&gt;
&amp;lt;?php use_helper(&#039;Object&#039;) ?&amp;gt;
&amp;lt;?php use_helper(&#039;ErrorMessages&#039;) ?&amp;gt;

&amp;lt;?php echo form_tag(&#039;page/update&#039;) ?&amp;gt;

&amp;lt;?php echo input_hidden_tag(&#039;id&#039;, $page-&amp;gt;getId()) ?&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Title&amp;lt;/strong&amp;gt; 
&amp;lt;?php echo object_input_tag($page, &#039;getTitle&#039;, array(&#039;size&#039; =&amp;gt; 80)) ?&amp;gt;
&amp;lt;?php echo error_on(&#039;title&#039;) ?&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Content:&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;
&amp;lt;?php echo object_textarea_tag($page, &#039;getContent&#039;, array(&#039;size&#039; =&amp;gt; &#039;80x10&#039;)) ?&amp;gt;
&amp;lt;?php echo error_on(&#039;content&#039;) ?&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;hr /&amp;gt;
&amp;lt;?php echo submit_tag(&#039;save&#039;) ?&amp;gt;
&amp;lt;?php if ($page-&amp;gt;getId()): ?&amp;gt;
  &amp;amp;nbsp;&amp;lt;?php echo link_to(&#039;delete&#039;, &#039;page/delete?id=&#039;.$page-&amp;gt;getId(), &#039;post=true&amp;amp;confirm=Are you sure?&#039;) ?&amp;gt;
  &amp;amp;nbsp;&amp;lt;?php echo link_to(&#039;cancel&#039;, &#039;page/show?id=&#039;.$page-&amp;gt;getId()) ?&amp;gt;
&amp;lt;?php else: ?&amp;gt;
  &amp;amp;nbsp;&amp;lt;?php echo link_to(&#039;cancel&#039;, &#039;page/index&#039;) ?&amp;gt;
&amp;lt;?php endif; ?&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;



&lt;p&gt;I could have used the short &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;&lt;code&gt;&amp;lt;?= ?&amp;gt;&lt;/code&gt; syntax to make this less verbose, but went with the most portable syntax. Note that there are equivalents for Rails&#039; &lt;code&gt;form_remote_tag&lt;/code&gt; etc..&lt;/p&gt;

&lt;h3&gt;Validation&lt;/h3&gt;

&lt;p&gt;Validation is set up in &lt;span class=&quot;caps&quot;&gt;YAML &lt;/span&gt;files (reminds me of Struts). For example, I wanted to make sure that both title and content are set for a wiki page. To validate an action, you have to add a &lt;span class=&quot;caps&quot;&gt;YAML &lt;/span&gt;file named after the action: in may case, I wanted to validate the &lt;code&gt;update&lt;/code&gt; action, so I added apps/frontend/modules/page/validate/update.yml:&lt;/p&gt;



&lt;pre&gt;
methods:
  post: [title, content]
  
fillin:
  enabled: on
  
names:
  title:
    required: yes
    required_msg: &#039;Please enter a title for the page&#039;
  content:
    required: yes
    required_msg: &#039;Please enter some content for the page&#039;
&lt;/pre&gt;



&lt;p&gt;Again, not as nice as Rails, but more declarative, perhaps. The &lt;code&gt;fillin&lt;/code&gt; option has to be enabled for auto-form-population to be turned on.&lt;/p&gt;

&lt;h3&gt;Other comments&lt;/h3&gt;

&lt;p&gt;I haven&#039;t mentioned the testing framework which is built into Symfony, as I didn&#039;t use. Note also that it supports separate development and production environments, like Rails, but they run concurrently: you access the development environment through a modified &lt;span class=&quot;caps&quot;&gt;URL, &lt;/span&gt;rather than by running the application in a different mode. That&#039;s quite nice.&lt;/p&gt;

&lt;p&gt;Another feature I liked is the console you get in development. This shows you log messages pertinent to the page, the &lt;span class=&quot;caps&quot;&gt;SQL &lt;/span&gt;queries run, and general stuff about the environment, presented as an &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;-ified menu across the top of the app.. I&#039;d love to see something like this in Rails.&lt;/p&gt;

&lt;p&gt;I started putting Ajax into the application, but in-place editors don&#039;t work very well with wiki pages (you need to be able to click on links in the page when a page is displayed, but the in-place editor turns the whole page into a clickable field which displays an edit form, as in Rails). So I abandoned that. I also experimented with using the &lt;span class=&quot;caps&quot;&gt;TITLE &lt;/span&gt;field as the primary key instead of ID (use of ID fields is encouraged in Symfony, as in Rails), but this was hard work, so I went back to IDs. I also didn&#039;t get round to authentication.&lt;/p&gt;

&lt;p&gt;That&#039;s as far as I went with the application, and I&#039;m unlikely to go further. I&#039;ve attached it to this post for anyone who&#039;s interested (licence is &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;).&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I put these few samples of Symfony code up to give a flavour of the differences and an impression of how it feels for a Rails programmer. It is not a thorough or complete evaluation. Try it for yourself. I have to say that the &lt;a href=&quot;http://www.symfony-project.com/tutorial/my_first_project.html&quot;&gt;tutorial&lt;/a&gt; on the Symfony website is pretty good; and you can also get a &lt;a href=&quot;http://www.symfony-project.com/book/trunk&quot;&gt;full book&lt;/a&gt; on Symfony from the site (or a print version). (Come on &lt;span class=&quot;caps&quot;&gt;DHH &lt;/span&gt;and Dave Thomas, when are we likely to see Agile Web Development for Rails given away? I&#039;ve already bought it twice.)&lt;/p&gt;

&lt;p&gt;Symfony has a lot going for it. It&#039;s pretty easy to get up and running. But by contrast with Rails, it is very verbose because of how &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;works. On the plus side, it is similar enough to Rails to make it fairly easy to transition to; and you can run it on normal web space at high speed without having to fork out for special hosting. That last point is very important to my mind. Coupled with the fact that there are lots of &lt;span class=&quot;caps&quot;&gt;PHP &lt;/span&gt;programmers out there already, or Java programmers looking for a lightweight framework but scared of Ruby, and I can see it growing at a reasonable pace. I would certainly consider it if I needed to write a scalable web application for myself; I&#039;ve even considered rewriting &lt;a href=&quot;http://flickrlilli.org.uk/&quot;&gt;Flickrlilli&lt;/a&gt; using it, to see if it makes a difference and to get a better comparison. You never know...&lt;/p&gt;</description>
 <comments>http://townx.org/blog/elliot/i_hear_a_symfony_rails_vs_the_symfony_php_framework#comments</comments>
 <category domain="http://townx.org/tech">tech</category>
 <enclosure url="http://townx.org/files/fmt_wiki.tar.gz" length="1652468" type="application/x-gzip" />
 <pubDate>Wed, 31 Jan 2007 07:58:12 -0600</pubDate>
 <dc:creator>elliot</dc:creator>
 <guid isPermaLink="false">539 at http://townx.org</guid>
</item>
</channel>
</rss>
