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

<channel>
	<title>Code Penguin &#187; PHP</title>
	<atom:link href="http://laurent.bachelier.name/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://laurent.bachelier.name</link>
	<description>Musings on software, internet and technology by Laurent Bachelier</description>
	<lastBuildDate>Thu, 16 Jun 2011 20:27:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Some clarifications on symfttpd</title>
		<link>http://laurent.bachelier.name/2011/03/some-clarifications-on-symfttpd/</link>
		<comments>http://laurent.bachelier.name/2011/03/some-clarifications-on-symfttpd/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 18:24:15 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=267</guid>
		<description><![CDATA[The basic idea is to start a server without any central configuration to maintain, and no need for any root access, hence generic virtual hosts features of Apache or lighttpd are not complete alternatives, as they at least require editing /etc/hosts. It uses the FastCGI backend (or &#8220;SAPI&#8221;) and can by default handle 3 concurrent [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:30364a44b1994a1c50b606c2b8fdf1711e44bc58'><p>The basic idea is to start a server without any central configuration to maintain, and no need for any root access, hence generic virtual hosts features of Apache or lighttpd are not complete alternatives, as they at least require editing <code>/etc/hosts</code>.</p>
<p>It uses the FastCGI backend (or &#8220;SAPI&#8221;) and can by default handle 3 concurrent requests, which is more than enough for development. On the production side, I only use symfttpd to generate the rewrite rules (since lighttpd is also my production server of choice). If you have an opcode cache installed (for instance APC or xcache), it will be used, as fastcgi processes are seldom restarted (by default every 100 requests, I use a higher number on production though). It also does not rely on any hacks to simulate a web request in the CLI: you are doing real requests using a real PHP HTTP backend.</p>
<p>One of the future improvements could be using <a href="http://php.net/manual/en/install.fpm.php">FPM</a> instead of FastCGI.</p>
<p><a href="https://github.com/laurentb/symfttpd">Symfttpd</a> can optionality use the <code><a href="http://php.net/manual/en/function.pcntl-fork.php">fork</a></code> function to provide two nice features: automatically restart when rewriting rules change, and display the access and error log. However, if you do not have fork support compiled in (it is enabled by default in at least Gentoo, Debian and Ubuntu), it does not mean only one request can be answered at a time (<a href="http://www.lighttpd.net/">lighttpd</a> does not need <code>fork()</code> by the way, which is one of the reasons it is very fast).</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2011/03/some-clarifications-on-symfttpd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfttpd 1.1.1 released</title>
		<link>http://laurent.bachelier.name/2011/02/symfttpd-1-1-1-released/</link>
		<comments>http://laurent.bachelier.name/2011/02/symfttpd-1-1-1-released/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 23:00:57 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[lighttpd]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=242</guid>
		<description><![CDATA[You can now use genconf without linking or copying it inside the project. It also makes the usage of mksymlinks more or less optional if you just want to use spawn. Not much else too see apart from small bug fixes and documentation improvements. Download symfttpd 1.1.1. More information on GitHub. There is also a [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:b73559fc46954f736eb03798d60f5a76cdd438bf'><p>You can now use <code>genconf</code> without linking or copying it inside the project. It also makes the usage of <code>mksymlinks</code> more or less optional if you just want to use <code>spawn</code>.</p>
<p>Not much else too see apart from small bug fixes and documentation improvements.</p>
<p>Download <a href="https://github.com/downloads/laurentb/symfttpd/symfttpd-1.1.1.tar.bz2">symfttpd 1.1.1</a>.<br />
More information on <a href="https://github.com/laurentb/symfttpd">GitHub</a>.</p>
<p>There is also a <a href="https://github.com/fabriceb/symfttpd/tree/symfony2">adaptation</a> of the current code for usage with Symfony2. However, it removes support of 1.x versions; a multiple-application update of symfttpd is coming soon.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2011/02/symfttpd-1-1-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfttpd 1.1.0 released</title>
		<link>http://laurent.bachelier.name/2011/02/symfttpd-1-1-0-released/</link>
		<comments>http://laurent.bachelier.name/2011/02/symfttpd-1-1-0-released/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 23:48:33 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[lighttpd]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=237</guid>
		<description><![CDATA[This version brings one huge usability change: you don&#8217;t have to restart spawn anymore when a file is added in the web/ directory root. Enjoy being truly lazy! Along with some miscellaneous enhancements, the output of the tools is now colored, and you can display lighttpd&#8217;s logs in the terminal with the -t option. As [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:903e6777568523d183d477167ea1070e07bd0301'><p>This version brings one huge usability change: you don&#8217;t have to restart <code>spawn</code> anymore when a file is added in the <code>web/</code> directory root. Enjoy being truly lazy!</p>
<p>Along with some miscellaneous enhancements, the output of the tools is now colored, and you can display lighttpd&#8217;s logs in the terminal with the <code>-t</code> option.</p>
<p>As always, suggestions and contributions are welcome.</p>
<p>Download <a href="https://github.com/downloads/laurentb/symfttpd/symfttpd-1.1.0.tar.bz2">symfttpd 1.1.0</a>.<br />
More information on <a href="https://github.com/laurentb/symfttpd">GitHub</a>.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2011/02/symfttpd-1-1-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A positive note</title>
		<link>http://laurent.bachelier.name/2011/01/a-positive-note/</link>
		<comments>http://laurent.bachelier.name/2011/01/a-positive-note/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 20:20:13 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[symfttpd]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=230</guid>
		<description><![CDATA[I have grown very fond of Symfony 1.4. It&#8217;s pretty much Symfony 1.2 with all the quicks ironed out. It showed me how much polish is important in a software project. It&#8217;s almost all I have been doing in my own little project after the main features were implemented, symfttpd: making it less annoying to [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:bb66278d89610a1c6688cd7e7074f081b41e94a1'><p>I have grown very fond of Symfony 1.4. It&#8217;s pretty much Symfony 1.2 with all the quicks ironed out. It showed me how much <em>polish</em> is important in a software project.</p>
<p>It&#8217;s almost all I have been doing in my own little project after the main features were implemented, <a href="https://github.com/laurentb/symfttpd">symfttpd</a>: making it less annoying to use, less unpredictable, etc. And I must say, the current stable version has at least one very annoying quirk (but if it&#8217;s documented, does it count as a feature?).</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2011/01/a-positive-note/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t forget the other kind of WTF</title>
		<link>http://laurent.bachelier.name/2010/08/dont-forget-the-other-kind-of-wtf/</link>
		<comments>http://laurent.bachelier.name/2010/08/dont-forget-the-other-kind-of-wtf/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 23:53:14 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[wtf]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=195</guid>
		<description><![CDATA[Sometimes, the code looks good, but it doesn&#8217;t mean that the whole project in itself is good. First, a project should be simple to install. The install documentation should exist and always be up to date. I encounter too many projects where &#8220;inside knowledge&#8221; is required to install the application, and you don&#8217;t know if [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:c04175613e3e20ff4a07ac0cf840ab340e34af5c'><p>Sometimes, the code looks good, but it doesn&#8217;t mean that the whole project in itself is good.</p>
<p>First, a project should be simple to install. The install documentation should exist and always be up to date. I encounter too many projects where &#8220;inside knowledge&#8221; is required to install the application, and you don&#8217;t know if it doesn&#8217;t work because you didn&#8217;t install it right or it just doesn&#8217;t work. There should be a single command (makefiles or shell scripts are here for that) for a single task. It should not require weird system settings (this is very annoying with PHP when a lot of the language is customizable through <code>php.ini</code>).</p>
<p>On a similar note, the architecture should be simple to comprehend. When it feels too much like &#8220;magic&#8221;, when a simple action has too many unsaid consequences, something is wrong. There should not be hundreds of classes and inheritances when an option would be enough (this is an idea found at least in Python and Symfony 1.4 that I quite like). Names should be readable and short, not everyone has or likes using auto-completion.</p>
<p>I&#8217;m not sure what creates this kind of WTF. Inexperienced but talented programmers? Programmers who think too high of themselves? Programmers that are <em>not</em><em> lazy enough?</em></p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/08/dont-forget-the-other-kind-of-wtf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>chmod 777 is evil</title>
		<link>http://laurent.bachelier.name/2010/07/chmod-777-is-evil/</link>
		<comments>http://laurent.bachelier.name/2010/07/chmod-777-is-evil/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 08:07:20 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=131</guid>
		<description><![CDATA[Well, chmod 666 is the true evil obviously, but people who use the chmod 777 trick really don&#8217;t want to bother with the different signification of x for files and folders, so they mark all files as executables. This makes ls in my terminal quite ugly, and is what motivated me to write yet another [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:5a49026651bd08aa4e816c1360225ee63973fc01'><p>Well, chmod 666 is the true evil obviously, but people who use the <em>chmod 777 trick</em> really don&#8217;t want to bother with the different signification of <code>x</code> for files and folders, so they mark all files as executables. This makes <code>ls</code> in my terminal quite ugly, and is what motivated me to write yet another rant!</p>
<p>Traditionally, the web server runs with a special, underprivileged user. Now, this is totally fine — I&#8217;ll get back to that later. However, when a developer starts a project, he naturally does it with his own account. This is fine, too. When he wants to test it, he installs a web server (let&#8217;s say Apache and mod_php<sup><a href="http://laurent.bachelier.name/2010/07/chmod-777-is-evil/#footnote_0_131" id="identifier_0_131" class="footnote-link footnote-identifier-link" title="I don&#039;t like much both of them, but more on that later">1</a></sup>), and tells the web server to use the project directory. However, the web server&#8217;s user can&#8217;t read, or at least can&#8217;t write in the directory. And here, our web developers asking for help gets recommended to &#8220;chmod 777&#8243;. Symfony even has a command for doing it, and it is a real shame.</p>
<p>It will work. It will also make an ugly git commit, and an ugly <code>ls</code>. Il will create files owned by the web server, and the developer is likely to use <code>sudo</code> before every command to work around the problems that will ensue, and it just gets insane.</p>
<p>Separation of privileges is what makes UNIX systems great. Let&#8217;s understand them and use them, please.</p>
<p>The obvious solution here is to run your development server under the development user. There is no need to separate when it&#8217;s for your own usage. There is a even better solution, embraced by almost every language but PHP: a way to start a web server on demand. I believe it was started by Ruby on Rails with WEBrick, and now every non-PHP framework has it. Python, by using <a href="http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface">WSGI</a> makes it very easy. I simulated this feature for Symfony by writing <a href="http://laurent.bachelier.name/2010/05/reducing-the-gap-between-symfony-and-non-php-frameworks/">symfttpd</a>. It&#8217;s actually simpler for the developer as there is no configuration or installation at all.</p>
<p>Enough about developers; it&#8217;s not their job to setup daemons and manage UNIX systems. Let&#8217;s talk about the real accomplices of the Devil: system administrators.</p>
<p>Yes, there are system administrators that don&#8217;t use permissions properly. And they are legion. I&#8217;ve seen horrors, up to &#8220;sudo svn up&#8221; on the production server, because half the files ended being owned by root. And then &#8220;chmod 777&#8243; on millions of files.</p>
<p>There are many solutions there; group inheritance with the <a href="http://en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_directories">setgid bit</a>, forcing the users to <code>su</code> as the web server user, or a deployment script (I&#8217;ve used the three of them for different situations).</p>
<p>Why is this important? Because it is often useful to separate users (one should not have access to the other&#8217;s projects in reading or writing), or to separate projects for security (one hacked project should not give access to the others).</p>
<p>I&#8217;ve seen it… done wrong:</p>
<ul>
<li>safe_mode for PHP. It doesn&#8217;t work and will disappear in newer versions anyway.</li>
<li>Only allowing FTP access to users, who can still upload a PHP script which will have access to everything (if run through the web server). Oh, and FTP sucks. Same issue with SSH and chroot.</li>
<li>Add the users to the <em>group</em> the web server is running as. Allows SSH access. Nice, but the PHP script trick will, again, defeat it.</li>
</ul>
<p>There is only one solution: use the &#8220;group&#8221; solution, but run a different PHP instance for each user. It is quite rarely used because the convenience of <em>Apache</em> and <em>mod_php</em>. But running PHP in the same <em>process</em> as the web server feels quite dangerous for me too. I think <em>mod_php</em> is an abomination.</p>
<p>I&#8217;ve done it for years with <em>Lighttpd</em>, <em>PHP</em> and <em>FastCGI</em> with a few alterations to Gentoo&#8217;s <code>spawn-fgci</code> init script (which is now able to handle multiple configurations without any alteration since a few months). My setup is very similar to <a href="http://redmine.lighttpd.net/wiki/lighttpd/HowToSetupFastCgiIndividualPermissions">that one</a>.</p>
<p>Note that while I mention PHP, this issue is not strictly related to PHP, yet seems widespread in PHP communities.</p>
<ol class="footnotes">
<li id="footnote_0_131" class="footnote">I don&#8217;t like much both of them, but more on that later</li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/07/chmod-777-is-evil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Exceptions</title>
		<link>http://laurent.bachelier.name/2010/07/exceptions/</link>
		<comments>http://laurent.bachelier.name/2010/07/exceptions/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 23:25:09 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=188</guid>
		<description><![CDATA[I see on a lot of projects stuff like this: function getStuff&#40;&#41; &#123; try &#123; return $this-&#62;retrieveStuff&#40;&#41; &#125; catch &#40;Exception $e&#41; &#123; return null; &#125; &#125; The issue, in this example, is not that we silence an error. It should be logged, but there could be a legitimate use for this. For instance, it requires [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:b93f51103415308f0ee5d5980768d593c9c4267f'><p>I see on a lot of projects stuff like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStuff<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  try
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">retrieveStuff</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span>
  catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The issue, in this example, is not that we silence an error. It should be logged, but there could be a legitimate use for this. For instance, it requires a connection to a remote server we have no control over, and we still want to serve the rest of the content to the user, as the information is not vital.</p>
<p>No, my issue it that we catch all errors, when the aim was to catch only one error (for instance &#8220;unable to connect to that remote server&#8221;). Imagine now there is a real bug in <code>retrieveStuff()</code>, it would still be interpreted by developers as a connection errors.</p>
<p>The solution is to have one exception type per error type (it sounds obvious said that way, doesn&#8217;t it?), and only catch the specific error, for instance <code>ConnectionError</code>.</p>
<p><!-- more --></p>
<p>PHP&#8217;s error handling is historically bad, and even though new features use exceptions, the legacy ones don&#8217;t. Or sometimes functions should trigger a fatal error but it is only a warning, and the code continues, which can trigger unwanted and hard-to-debug results. There are amazing plugins for Symfony that convert errors to exceptions (and warnings seem to be handled properly, i.e. they are logged and don&#8217;t cause the page to fail). It&#8217;s a start.</p>
<p>However, even when you get exceptions, you can&#8217;t always filter them easily. For instance, in Symfony, there are many different errors that would throw the same class. Symfony has a handful of exceptions, Doctrine has a bit more (though they can be quite meaningless!). Overall, there are defined &#8220;by module&#8221; than &#8220;by error&#8221;.</p>
<p>Comparatively, <a href="http://docs.python.org/tutorial/errors.html">Python&#8217;s handling of exceptions</a> is exceptional<sup><a href="http://laurent.bachelier.name/2010/07/exceptions/#footnote_0_188" id="identifier_0_188" class="footnote-link footnote-identifier-link" title="sorry">1</a></sup>. There are exceptions for everything, and most of the time errors are handled by only checking the class and not the contents of the exception. It is probably the feature I love the most about Python. With the <code>else</code>, <code>finally</code>, and <code>with</code> statements, it is almost a pleasure to handle errors.</p>
<ol class="footnotes">
<li id="footnote_0_188" class="footnote">sorry</li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/07/exceptions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I wouldn&#8217;t use Symfony for a new project</title>
		<link>http://laurent.bachelier.name/2010/07/why-i-wouldnt-use-symfony-for-a-new-project/</link>
		<comments>http://laurent.bachelier.name/2010/07/why-i-wouldnt-use-symfony-for-a-new-project/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 23:44:33 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[troll]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=181</guid>
		<description><![CDATA[Symfony is pretty good for a PHP framework — it&#8217;s probably still one of the better ones. While Symfony is open source, its development clearly isn&#8217;t open. Nowadays, it is mainly unmaintained. Well, it&#8217;s maintained by Sensio, which is very closed towards outsiders, and doesn&#8217;t apply fixes for versions below 1.3 even when patches are [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:b8451b92ee26e7ee79ddae47feca90148b5ecd27'><p>Symfony is pretty good for a PHP framework — it&#8217;s probably still one of the better ones. While Symfony is open source, its development clearly isn&#8217;t open.</p>
<p>Nowadays, it is mainly unmaintained. Well, it&#8217;s maintained by <a href="http://www.sensio.com/">Sensio</a>, which is very closed towards outsiders, and doesn&#8217;t apply fixes for versions below 1.3 even when patches are handed ready to them. Which means for instance that the official 1.0 doesn&#8217;t work with PHP 5.3 even though the fixes are available and straightforward.</p>
<p>I will pass on the worrisome attitude towards security of the most used plugin as I&#8217;ve talked about it extensively already. <a href="https://groups.google.com/group/symfony-devs/browse_thread/thread/37c3d5aef3b8b346">Constant</a> <a href="https://groups.google.com/group/symfony-devs/browse_thread/thread/127fa4c30f19180e">reminders</a> don&#8217;t even work.</p>
<p>There is much more activity towards Symfony2, which might explain the lack of updates to the 1.x branches. Symfony2 introduces more decoupling, which should avoid many bugs reported but ignored by the development team, probably because they are boring to fix and require very deep knowledge in Symfony&#8217;s architecture — I would have tried to fix them myself if I had the time and motivation; I&#8217;m afraid I usually take the easy route and work around them.</p>
<p>But how does Symfony2 looks for a developer? What I&#8217;ve seen is fairly standard and boring, and sometimes looks like sad attempts of reimplementing Python features in PHP. Why not use Python then?</p>
<p>Doctrine2 is even worse — it&#8217;s the same broken, undocumented API. Propel 1.5, with a minimum set of changes, became much more powerful and easy to use for a developer. At least there&#8217;s hope on this side.</p>
<p>Overall, it seems the Symfony lead developers don&#8217;t take much input from the community (like the decision to follow Zend conventions), and focus on making something fun to write, instead of fun to use. I have the choice between an undermaintened version and a future version which will break compatibility without giving me much advantages; moreover some of the stuff that was shown in conferences isn&#8217;t event implemented yet. I&#8217;m not used to see that in the free software word.</p>
<p>Time to switch?</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/07/why-i-wouldnt-use-symfony-for-a-new-project/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Reducing the gap between Symfony and non-PHP frameworks</title>
		<link>http://laurent.bachelier.name/2010/05/reducing-the-gap-between-symfony-and-non-php-frameworks/</link>
		<comments>http://laurent.bachelier.name/2010/05/reducing-the-gap-between-symfony-and-non-php-frameworks/#comments</comments>
		<pubDate>Sun, 23 May 2010 23:01:09 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[symbolic links]]></category>
		<category><![CDATA[symfttpd]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=172</guid>
		<description><![CDATA[Something that always annoyed me is how tedious it is to install a Symfony project on a machine. Since I frequently need to intervene quickly on a project for work, and I was getting a brand-new machine, I really didn&#8217;t want to create an apache vhost (let alone install Apache: it&#8217;s painfully slow and its [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:dff9fd37718ad21821c464daf7fe8459d14517f6'><p>Something that always annoyed me is how tedious it is to install a Symfony project on a machine. Since I frequently need to intervene quickly on a project for work, and I was getting a brand-new machine, I really didn&#8217;t want to create an apache <em>vhost</em> (let alone install Apache: it&#8217;s painfully slow and its configuration is obscure and hard to debug), edit my <code>/etc/hosts</code> file, etc. for each project.</p>
<p>Moreover, developers are not system administrators and should not have to do complicated setups, especially when it turns out to be badly set up, and problems are &#8220;resolved&#8221; by &#8220;chmod 777&#8243; or &#8220;chmod 666&#8243; (which is indeed <a href="http://wordpress.org/development/2010/04/file-permissions/">evil</a>), a very sad but true practice promoted even by the developers of Symfony since there is a <code>symfony fix-perms</code><code> command that basically does that. It should have been named </code><code>symfony break-perms</code> or <code>symfony please-make-things-insecure-i-want-to-go-back-to-windows</code> or never been made.</p>
<p>On most non-PHP frameworks, there is a small embedded webserver that you can run on-demand. <strong>No configuration needed.</strong> Moreover, no special rights needed: a simple user can start it.</p>
<p>Since there was no such webserver written in PHP that was able to run Symfony properly, I chose to auto-configure <a href="http://www.lighttpd.net/">lighttpd</a> with a simple tool called <em>symfttpd</em>. The <code>genconf</code> tool was born.</p>
<p>However, I encountered another issue I didn&#8217;t think of before: for each project, I had to <strong>create symbolic links</strong> to the Symfony source code (another practice of the Symfony community, and there is no proper alternative in the PHP world). Hence, I created <code>mksymlinks</code>. For the developer, it is very simple to use: configure once on the machine, once per project, and that&#8217;s it.</p>
<p><code>genconf</code> only generates a configuration, which is still very practical for a system administrator; moreover it is flexible and well-tested. But it still required the develop to configure something, and there still was the rights problem.</p>
<p>Hence I created <code>spawn</code> which handles <strong>starting and stopping the webserver, just like non-PHP frameworks do</strong>. As a nice addition, it keeps server and PHP logs in the <code>log</code> folder of the project.</p>
<p><em>symfttpd</em> has even more uses; one I didn&#8217;t think of at first was that it can automate the installation of a project on a continuous integration platform, and can start a webserver for functional testing (both are used daily at work).</p>
<p>One of the most important aspects of <em>symfttpd</em> is that <strong>all tools are independent</strong>: you can use only <code>mksymlinks</code> or <code>genconf</code> (though <code>spawn</code> more or less requires the use of both, it isn&#8217;t set in stone). A system administrator will find use in <code>mksymlinks</code> and <code>genconf</code>, and a developer more in <code>mksymlinks</code> and <code>spawn</code>.</p>
<p>You&#8217;ll find extensive documentation on the <a href="http://github.com/laurentb/symfttpd">project page</a>; what will follow is a quick tutorial for developers.</p>
<p><!-- more --></p>
<p><strong>Install the necessary packages:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Debian/Ubuntu</span>
<span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-cgi php5-cli lighttpd
&nbsp;
<span style="color: #666666; font-style: italic;"># Gentoo</span>
emerge php <span style="color: #666666; font-style: italic;"># with USE=&quot;cli cgi&quot;</span>
emerge lighttpd <span style="color: #666666; font-style: italic;"># with USE=&quot;fastcgi&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Macports</span>
port <span style="color: #c20cb9; font-weight: bold;">install</span> php5 +fastcgi <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> port <span style="color: #c20cb9; font-weight: bold;">install</span> lighttpd
&nbsp;
<span style="color: #666666; font-style: italic;"># Windows</span>
Nice try.</pre></div></div>

<p><strong>Get the symfttpd source code:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>laurentb<span style="color: #000000; font-weight: bold;">/</span>symfttpd.git</pre></div></div>

<p>There are also archives you can download <a href="http://github.com/laurentb/symfttpd/downloads">here</a> if you want to avoid <em>git</em> or bleeding-edge changes.</p>
<p><strong>Basic configuration:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># notice the dot before symfttpd.conf.php</span>
<span style="color: #007800;">$EDITOR</span> ~<span style="color: #000000; font-weight: bold;">/</span>.symfttpd.conf.php</pre></div></div>

<p>Enter something like that:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sf_path'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'1.0'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/home/myuser/symfony/1.0'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sf_path'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'1.4'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/home/myuser/symfony/1.4'</span><span style="color: #339933;">;</span></pre></div></div>

<p>Of course, you have to have to adapt it to the Symfony versions you have installed and where you put them.</p>
<p><strong>Configure the project:</strong><br />
If the project is using Symfony 1.4 in the <code>lib/vendor/symfony</code>, you don&#8217;t need to do anything. In case it is different, or to be on the safe side, create the file 	<code>config/symfttpd.conf.php</code> in your project. After, add the file to your project&#8217;s version control repository. If you&#8217;re lucky, someone already did it for you.</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>myproject
<span style="color: #666666; font-style: italic;"># this time, no dot</span>
<span style="color: #007800;">$EDITOR</span> config<span style="color: #000000; font-weight: bold;">/</span>symfttpd.conf.php</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'want'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'1.3'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// The version of Symfony used by your project</span>
<span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lib_symlink'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'lib/vendor/symfony'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// lib/vendor/symfony will lead to the &quot;lib&quot; directory of Symfony</span></pre></div></div>

</pre>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">/</span>symfttpd<span style="color: #000000; font-weight: bold;">/</span>mksymlinks</pre></div></div>

<p>You're done.<br />
It will <strong>create symbolic links for plugins</strong> too, even if the version of Symfony (1.0 for instance) doesn't handle them!</p>
<p>To start the server:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">/</span>symfttpd<span style="color: #000000; font-weight: bold;">/</span>spawn</pre></div></div>

<p>It will then tell you how to access it. It's time to stop fighting with old, unpredictable software like Apache and start developing again!</p>
<p><strong>What's coming in future releases:</strong></p>
<ul>
<li>Colors</li>
<li>Interactive configuration</li>
<li>Server/PHP logs displayed in the terminal</li>
<li>Handling "sample" files</li>
<li>Custom configuration support on various places</li>
</ul>
<p>Contributors are welcome.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/05/reducing-the-gap-between-symfony-and-non-php-frameworks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>And I thought sfDoctrineGuardPlugin was bad…</title>
		<link>http://laurent.bachelier.name/2010/04/and-i-thought-sfdoctrineguardplugin-was-bad%e2%80%a6/</link>
		<comments>http://laurent.bachelier.name/2010/04/and-i-thought-sfdoctrineguardplugin-was-bad%e2%80%a6/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 10:34:09 +0000</pubDate>
		<dc:creator>Laurent</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[random numbers]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://laurent.bachelier.name/?p=167</guid>
		<description><![CDATA[Update: You can safely ignore this angry rant as the issues have been fixed. I am speechless. While doAuthPlugin looks interesting (especially because it uses inheritance and not some silly secondary Profile table), on the topic of security it is worse than sfDoctrineGuardPlugin. Let&#8217;s have a quick look at doAuthTools. public static function rememberHash&#40;User $user&#41; [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:b599bbc9440280bc0bad2d9d0b3f4916b61ef034'><p><em><strong>Update: You can safely ignore this angry rant as the issues have been fixed.</strong></em></p>
<p>I am speechless. While <a href="http://www.symfony-project.org/plugins/doAuthPlugin">doAuthPlugin</a> looks interesting (especially because it uses inheritance and not some silly secondary Profile table), on the topic of security it is worse than <a href="http://laurent.bachelier.name/2010/02/security-is-not-easy/">sfDoctrineGuardPlugin</a>.</p>
<p>Let&#8217;s have a quick look at <a href="http://github.com/DavertMik/doAuthPlugin/blob/6a65d6d63e393a6c526134c48fb38ac622e3ec27/lib/doAuthTools.class.php">doAuthTools</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> rememberHash<span style="color: #009900;">&#40;</span>User <span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'-'</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPassword</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>There&#8217;s the use of md5, which doesn&#8217;t doesn&#8217;t resist long to rainbow tables attacks nowadays, but the worst is what is used. No random data at all, no salt.<br />
The user id is most of the time public, the username almost always is, and for absolutely no reason <strong>only the first five characters of the password are used</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> activationCode<span style="color: #009900;">&#40;</span>User <span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p><code>created_at</code> is easy to guess, <code>time()</code> is easy to guess and the rest is public. Again, what&#8217;s with the use of <code>substr()</code>? I would also guess the author wanted to use the password and not the username.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> generatePassword<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">9999</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now this is just sad. Sure, even with the use of a-f0-9 there is still 16^8 possible passwords, but why not spend a little time and try to use all the available letters? It also means that if you know the user id and username, you know you only have 16^5 <em>rememberHashes</em> to brute-force, which is easily doable.</p>
<p>We&#8217;ve already seen that using <code>rand()</code> is bad, but restricting it is even worse. Why on earth? To sum up, the password is constructed from a poor random algorithm with under <abbr title="Not a good power level">9000</abbr> possible values, and an easily predictable timestamp.</p>
<p>Frightening.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://laurent.bachelier.name/2010/04/and-i-thought-sfdoctrineguardplugin-was-bad%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

