<?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>P'unk Avenue Window &#187; Development</title>
	<atom:link href="http://window.punkave.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://window.punkave.com</link>
	<description></description>
	<lastBuildDate>Sat, 24 Jul 2010 01:15:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google&#8217;s new &#8220;App Inventor&#8221; is a game-changer</title>
		<link>http://window.punkave.com/2010/07/12/googles-new-app-inventor-could-be-a-game-changer/</link>
		<comments>http://window.punkave.com/2010/07/12/googles-new-app-inventor-could-be-a-game-changer/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 23:36:27 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Videos]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1184</guid>
		<description><![CDATA[
There are now 10,000 Android developers, as opposed to 40,000 for the iPhone. And Google is gearing up to release App Inventor, a tool for nontechnical Android app developers that is strikingly similar to the Scratch programming environment for kids. Meanwhile Android phones themselves are catching up quickly, although the iPhone 4 remains the coolest [...]]]></description>
			<content:encoded><![CDATA[<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/8ADwPLSFeY8&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8ADwPLSFeY8&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<p>There are now 10,000 Android developers, as opposed to 40,000 for the iPhone. And Google is gearing up to release <a href="http://appinventors.googlelabs.com/">App Inventor</a>, a tool for nontechnical Android app developers that is strikingly similar to the <a href="http://scratch.mit.edu/">Scratch</a> programming environment for kids. Meanwhile Android phones themselves are catching up quickly, although the iPhone 4 remains the coolest thing around.</p>
<p>Like many others I&#8217;m sure, I considered developing a tool like this and abandoned it after coming to grips with Apple&#8217;s harsh policies on the subject of alternative programming environments:<br />
<code><br />
3.3.1 — Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).<br />
</code><br />
Google&#8217;s reliance on crowdsourced quality control for apps isn&#8217;t perfect but it is beginning to add up to a real difference in spirit. As Android phone sales grow, making development for it an even more viable proposition, content creators will eventually vote with their feet for the platform where they feel most welcome and walk away from the walled garden. </p>
<p>I have an iPhone and I love it, in part because of Apple&#8217;s excellent quality control in the core applications. If Apple&#8217;s competition here were as bad as their competition in the MP3 player market&mdash; companies with almost no grasp of design&mdash; I wouldn&#8217;t doubt the outcome for a moment. But Android also has quality designers at play. Google&#8217;s approach to design may be a bit plodding and obsessed with A/B testing, but it does get results.</p>
<p>Apple knows they must continue to release cutting-edge hardware, but they don&#8217;t seem to grasp what it takes to maintain a welcoming developer platform once there are viable alternatives in the game.</p>
<p>I&#8217;m going out on a limb here: a year from now there will be as many Android apps as iPhone apps. 18 months from now Android phone sales will surpass iPhone sales. Apple will still have the sexiest phones, and will still command a premium price for them. But inside two years the iPhone will occupy a niche similar to that of the Macbook. </p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/07/12/googles-new-app-inventor-could-be-a-game-changer/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Symfony 2 hub-bub</title>
		<link>http://window.punkave.com/2010/06/10/symfony-hub-bub/</link>
		<comments>http://window.punkave.com/2010/06/10/symfony-hub-bub/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 19:01:25 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1169</guid>
		<description><![CDATA[Symfony is the best framework for building web applications in PHP. The forthcoming Symfony 2 is a dramatic improvement and a complete rewrite with many new features and, even more importantly, better software architecture. Enthusiasts may have heard about the State of Symfony 2 Online Conference to be held on June 23rd. Fabien and the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.symfony-project.org/">Symfony</a> is the best framework for building web applications in PHP. The forthcoming Symfony 2 is a <a href="http://www.symfony-reloaded.org/">dramatic improvement and a complete rewrite with many new features</a> and, even more importantly, better software architecture. Enthusiasts may have heard about the <a href="http://www.symfony-live.com/">State of Symfony 2 Online Conference</a> to be held on June 23rd. Fabien and the Sensio team have encouraged folks to become &#8220;Symfony conference hubs&#8221; and invite others to attend the conference from our offices and enjoy the benefits of our lovely projector, coffee, etc. And P&#8217;unk Avenue is definitely all about it. Please RSVP by commenting here. </p>
<p>WHAT: Symfony 2 Live Conference<br />
WHERE: P&#8217;unk Avenue offices, 1168 E. Passyunk Ave, Philadelphia PA<br />
WHEN: 11am Wednesday, June 23rd</p>
<p>Thanks to our hub status, <b>You do not have to buy your own Symfony 2 ticket</b> to attend at our office.</p>
<p>We&#8217;re looking forward to discussion and possibly busting out the Symfony 2 sandbox and experimenting after the conference.</p>
<hr />
Amid the excitement about Symfony 2, this would be a good time to mention our ongoing support for Symfony 1.4, and by extension Apostrophe 1.x. If Symfony 2.0 is coming, does that mean we&#8217;re going to abandon Symfony 1.x and Apostrophe 1.x?</p>
<p>No, not by a long shot, not any time soon. Symfony 2 will not be backwards compatible in a &#8220;super easy upgrade path&#8221; way, which is a valid choice to make improvements that would otherwise be impossible but an obvious problem for existing projects. And we have plenty of those. What&#8217;s more, Symfony 2 requires PHP 5.3.x at a minimum, and we know how tough it can be to move clients along just to PHP 5.2.x. </p>
<p>Fortunately, Sensio had the wisdom to make Symfony 1.4 a long-term-support release. And since Apostrophe 1.x is happily married to Symfony 1.4, that means we&#8217;re all in good shape.</p>
<p>Symfony 1.4 is supported until November of 2012, and Apostrophe 1.x will also be supported until at least November of 2012. </p>
<p>At some point, Apostrophe 2.x will come into being and it will be based on Symfony 2, but we have many client and internal projects that are purring away happily on Symfony 1.4 and we have absolutely no interest in abandoning it. So you can very safely pursue client projects based on the current stable releases of Apostrophe.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/06/10/symfony-hub-bub/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>No Symfony users group meeting this week</title>
		<link>http://window.punkave.com/2010/05/10/no-symfony-users-group-meeting-this-week/</link>
		<comments>http://window.punkave.com/2010/05/10/no-symfony-users-group-meeting-this-week/#comments</comments>
		<pubDate>Mon, 10 May 2010 16:48:21 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/2010/05/10/no-symfony-users-group-meeting-this-week/</guid>
		<description><![CDATA[We&#8217;re looking at doing a meeting the following week or possibly next month. Fact is, we&#8217;re busy! 
Speaking of Symfony and being busy, if this announcement disappoints you&#8212; if you&#8217;re eager to hobnob with other Symfony developers&#8212; may I suggest you apply to work here? You&#8217;ll have all the Symfony you can eat! We&#8217;re particularly [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re looking at doing a meeting the following week or possibly next month. Fact is, we&#8217;re busy! </p>
<p>Speaking of Symfony and being busy, if this announcement disappoints you&mdash; if you&#8217;re eager to hobnob with other Symfony developers&mdash; may I suggest you <a href="http://jobs.37signals.com/jobs/6723">apply to work here</a>? You&#8217;ll have all the Symfony you can eat! We&#8217;re particularly eager to talk to experienced PHP5 framework coders, and to Ruby on Rails coders who are open to working in PHP (sekrit plans to convert us to Ruby are a bit unrealistic given the <a href="http://www.apostrophenow.com/">depth of our commitment to PHP and Symfony</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/05/10/no-symfony-users-group-meeting-this-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We&#8217;re hiring a new developer</title>
		<link>http://window.punkave.com/2010/05/03/were-hiring-a-new-developer/</link>
		<comments>http://window.punkave.com/2010/05/03/were-hiring-a-new-developer/#comments</comments>
		<pubDate>Mon, 03 May 2010 20:25:15 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[help wanted]]></category>
		<category><![CDATA[job]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1115</guid>
		<description><![CDATA[
Things are moving pretty fast lately on our corner of E. Passyunk and Federal. Apostrophe is rolling along at a full clip and we have all sorts of other exciting projects we&#8217;re in the midst of. Olivia Rabe recently joined the team to work closely with our clients on issues of content strategy and Apostrophe [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://window.punkave.com/wp-content/uploads/2010/05/4502850348_47bb681625_b-e1272918036436.jpeg" alt="" title="P&#039;unk Team v7" width="500" height="375" class="alignnone size-full wp-image-1125" /></p>
<p>Things are moving pretty fast lately on our corner of E. Passyunk and Federal. <a href="http://apostrophenow.com">Apostrophe</a> is rolling along at a full clip and we have all sorts of other exciting projects we&#8217;re in the midst of. Olivia Rabe <a href="http://twitter.com/punkave/status/12469462512">recently joined the team</a> to work closely with our clients on issues of content strategy and Apostrophe support. We&#8217;re even beginning to expand our studio space into the adjacent building.</p>
<p>If this sounds at all interesting to you, the best news is that you might be able to help us fill some of our new space: We&#8217;re looking to make another addition to the team so we can continue to build these amazing applications and still go home on time. Right now we are looking for a new developer, somebody who would assist in the creation of new Apostrophe features and collaborate on development of products for our clients.</p>
<p>If you think you might be the right fit, or know someone who is, read on after the cut.<br />
<span id="more-1115"></span></p>
<p>P’unk Avenue is a web design and development team located in Philadelphia that creates websites and applications for higher education and business clients. We are also the creators of Apostrophe, an open source CMS built on top of the Symfony framework.</p>
<p>We are eight people looking for another developer to add our team. Since we are a small shop we all get involved in various aspects of each project. We believe that is a good thing and are looking for someone that enjoys being engaged in a project on many levels. Your role would involve a high level of collaboration with the entire team as you help us see projects through from designing and prototyping to development and deployment.</p>
<p>Our ideal colleague meets several of these criteria:</p>
<p>Fluency and comfort with PHP &#038; MySQL<br />
A deep and practical understanding of MVC frameworks (Ruby on Rails, Zend Framework, CakePHP, Django and CodeIgniter all apply, but experience with Symfony is especially desirable)<br />
A working knowledge of ORMs such as Doctrine, Propel or ActiveRecord<br />
Gets excited about things like web services, rapid prototyping and open source projects<br />
A passion for using Test Driven Development to write tight, well tested code<br />
A love for collaborating with a small team to solve tough problems<br />
A sense of humor and an ability to stay cool under pressure</p>
<p>This job does require you to work out of our (awesome) Philadelphia studio. We have great flexibility in other areas, but we believe that having our team in the same location on a regular basis benefits the products that we create.</p>
<p>Of note, we organize various community events like the Junto and Ignite Philly. We are very interested in engaging in and encouraging deeper conversations about stimulating ideas. The type of person that is also stimulated by thinking and acting on issues they care about would be a good fit on our team. It is not required, but the opportunity to help organize these events is a possibility for any member of our team.</p>
<p>Interested?</p>
<p>If you feel that you are a good fit, please send resumes and whatever other documentation that you think best represents why we should consider you to: jobs@punkave.com.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/05/03/were-hiring-a-new-developer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faster, Windows PHP! Kill! Kill!</title>
		<link>http://window.punkave.com/2010/04/26/faster-windows-php-kill-kill/</link>
		<comments>http://window.punkave.com/2010/04/26/faster-windows-php-kill-kill/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 22:23:20 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1106</guid>
		<description><![CDATA[IN WHICH our hero is narrowly saved by vague memories of a really dull presentation by some guys in suits.
You may recall my recent post on speeding up PHP on Linux without changing your PHP code. Those techniques have become standard practice around here, and the article has since been retweeted, linked to, engraved on [...]]]></description>
			<content:encoded><![CDATA[<p><i>IN WHICH our hero is narrowly saved by vague memories of a really dull presentation by some guys in suits.</i></p>
<p>You may recall my recent post on <a href="http://window.punkave.com/2010/03/08/faster-php-kill-kill/">speeding up PHP on Linux without changing your PHP code</a>. Those techniques have become standard practice around here, and the article has since been retweeted, linked to, engraved on an unobtanium disc embedded in a space probe to be launched next week by the Malaysian space forces, et cetera. So it seems we have the Linux PHP thing down to a science, for now.</p>
<p>But not every shop runs Linux, and one of our clients has asked us to deploy in a Windows environment. We&#8217;ve deployed PHP sites for them before, but that was in the Symfony 1.0 days, and there just weren&#8217;t nearly as many class files to compile. When we set out to deploy a modern site built with <a href="http://www.apostrophenow.com/">Apostrophe</a>, our content management system based on Symfony 1.4 and Doctrine, we were reminded that out-of-the-box PHP is slow, slow, slow.</p>
<p>I would gladly have addressed this the same way we do it on Linux: FastCGI, APC and Apache&#8217;s worker thread MPM. And in fact Apache for Windows seems to only support a special threaded MPM under Windows anyway, so that part is already familiar.</p>
<p>Unfortunately, the official PHP infrastructure for Windows has, frankly, undergone a bit of code rot lately:</p>
<p>The PHP binaries don&#8217;t seem to include a CGI/FastCGI binary! Shoot. Well, maybe APC alone will be enough. But APC is not standard with the Windows PHP binaries, so I need to get it from PECL. Okay, but <a href="http://pecl4win.php.net/">the PECL for Windows site</a> is &#8220;temporarily out of service.&#8221; A new solution is coming, but it&#8217;s not here yet. </p>
<p>Searches led me to <a href="http://downloads.php.net/pierre/">Pierre Joye&#8217;s folder on downloads.php.net</a>. Pierre is a core PHP developer, so I trust him, no problem there. But the version of APC found there just locks up Windows PHP, at least in my tests. I investigated alternative PHP bytecode caches and wound up with xcache. xcache worked for a while, then started spewing errors about classes being redefined, and always began doing so again within a few page views after each restart of Apache.</p>
<p>Yuck!</p>
<p>Fortunately, by this point a vague memory was stirring somewhere in my geeky cortex. I was in Paris&#8230;  I was full of pain au chocolat&#8230; I was very sleepy&#8230; two guys in suits were droning on and on about something while the crowd ignored them&#8230; AHA! Those Microsoft guys at Symfony Live! They were talking about speeding up PHP on Windows. They even mentioned hiring Pierre Joye to help out. But they didn&#8217;t demonstrate anything on Symfony, so I wasn&#8217;t paying a lot of attention&mdash;</p>
<p>Just enough as it turns out. The deal is this: Microsoft knows that PHP has, historically, sucked on Windows. And they have taken steps. And this is good news for the rest of us.</p>
<p>PHP can now be installed via the <a href="http://www.microsoft.com/web/platform/phponwindows.aspx">Microsoft Web Platform installer</a>. That gives you single-threaded PHP running via fastcgi&mdash; exactly like my Linux setup, except for the bytecode cache part.  And now the new <a href="http://www.iis.net/download/WinCacheForPHP">Windows Cache Extension for PHP</a> delivers a bytecode cache, equivalent to APC.</p>
<p>The end result is definitely in the ballpark with the performance of my Linux solution. Since I haven&#8217;t tested them on the same hardware (both boxes were VMs, and they were provided by different datacenters), I cannot say for certain which was faster. The Microsoft speakers at Symfony Live characterized it as better but still not as fast as the best PHP setups on Apache. At any rate it&#8217;s a big improvement and well worth your time if you need to host on Windows.</p>
<p>So here&#8217;s a HOWTO for configuring Symfony and PHP on Windows with good performance:</p>
<p>To configure IIS for Symfony:</p>
<p>1. Make sure IIS is installed. I know, right?</p>
<p>We want IIS 7. IIS 7 features an excellent importer for mod_rewrite rules, and Symfony loves mod_rewrite rules.</p>
<p>2. Install PHP from the <a href="http://www.microsoft.com/web/platform/phponwindows.aspx3">Microsoft Web Platform</a>. Click that link from IE running on your server (hint: remote desktop connection) for the easiest download-and-install process.</p>
<p>3. Install <a href="http://www.iis.net/download/WinCacheForPHP">Windows Cache for PHP</a> to  get acceptable speed from the above. I installed version 1.0 because 1.1 is in beta. The beta does look interesting because it has an alternate PHP session handler that uses shared memory. You&#8217;d have to configure symfony to actually use that feature I believe (welcome to factories.yml).</p>
<p>4. Let&#8217;s say your project&#8217;s short name (aka &#8220;Unix name&#8221;) is <tt>mysite</tt>. So copy your Symfony project to <tt>c:\mysite</tt>. (I&#8217;m assuming a virtual machine for a single client project. Choose a better folder structure if you&#8217;re deploying lots of sites on this box.) You can set up cygwin to allow ssh access and rsync those files with project:deploy, and in fact we do, but that&#8217;s a subject for another day. FTP also works.</p>
<p>5. Launch the IIS manager (Start -> Administrative Tools -> IIS Manager). </p>
<p>6. Open the server&#8217;s icon, then &#8220;Sites,&#8221; then delete the &#8220;default site&#8221; entry.</p>
<p>7. Add a new site entry called <tt>mysite</tt>. Map the site&#8217;s web folder to be the web subfolder of the Symfony project which you should have copied to <tt>c:\mysite</tt> by now. So the web folder path would be <tt>c:\mysite\web</tt>. Assign it to port 80. Do NOT set the web folder to be the root of your project! That is very dangerous as it exposes your databases.yml file. Point it to the web subfolder.</p>
<p>8. Always clear your Symfony cache after copying a site to a new server. At the command shell (start-&gt;run-&gt;cmd.exe), type:<br />
<tt><br />
cd \mysite<br />
php symfony cc<br />
</tt><br />
10. PHP needs write access to <tt>c:\windows\temp</tt> to store session data in order for logon sessions to work. You should have no trouble here on a new setup with just IIS I suspect, but if you previously ran Apache you might need to clean up. Clobber any existing session files in <tt>c:\windows\temp</tt>. Note that this is also the folder where the PHP error log file is found:</p>
<p><tt>c:\windows\temp\php-errors.log</tt></p>
<p>You can watch that file using a Cygwin shell and the tail -f command, or peek at it as needed with a text editor.</p>
<p>9. Try the site out, with a frontend controller name in the URL. You&#8217;ll get the home page but subpages won&#8217;t work yet without manually putting the controller name back in the URL. In IE running on the server itself, visit:</p>
<p><tt>http://localhost/index.php</tt></p>
<p>10. We need to add the mod_rewrite rules that remove the need for `/index.php`. But IIS doesn&#8217;t have mod_rewrite. Fortunately IIS7 has its own URL rewriting feature&#8230; and it can import your rules. </p>
<p>In the IIS manager, double-click <tt>mysite</tt>, then double-click &#8220;URL Rewrite.&#8221; In the &#8220;Actions&#8221; area at right, click &#8220;Import Rules&#8221; under &#8220;Inbound Rules.&#8221; </p>
<p><b>Edit:</b> if &#8220;Inbound Rules&#8221; is missing, close &#8220;URL Rewrite&#8221; and then open that feature again. Also try adding one empty rule manually first. The &#8220;incredible disappearing/reappearing &#8216;Inbound Rules&#8217; feature&#8221; appears to be a bug in the IIS manager.</p>
<p>Paste the mod_rewrite rules from your <tt>web/.htaccess</tt> file. IIS will do a pretty snazzy job of converting them when you click Import (but if you have fancy rules that go beyond the usual Symfony rules, give the end results a careful look-see). Then click &#8220;Apply.&#8221;</p>
<p><b>Edit:</b> IIS won&#8217;t tell you, but the settings you just created live in a file called <tt>web.config</tt> in the web subfolder of your project. <b>You must not crush this file</b> when you sync your project. Add the file to your project, or rsync exclude it if you&#8217;re using cygwin and project:deploy. Since you might want to add more rules to it manually I generally recommend the former. But one disadvantage of adding it to your project is that any edits you make in the GUI will get clobbered on future syncs if you don&#8217;t manually copy the resulting changes from web.config on the server back to your project. </p>
<p>11. Try the site again. You should be able to browse the entire site now.</p>
<p>12. Whoops, you can&#8217;t log in because IIS is hijacking the 401 Unauthorized error page. To fix that, go back to the IIS Manager pane for <tt>mysite</tt>. Double-click &#8220;Modules&#8221; and remove the &#8220;Custom Error&#8221; module. </p>
<p>Now your site&#8217;s login page will appear properly. Also your custom 404 and 500 error pages.</p>
<p>That&#8217;s it &#8211; you should be ready to go with much speedier Windows PHP.</p>
<p>Note that for the time being the Microsoft Web Platform seems to offer only PHP 5.2.13. This is a stable and sane choice and until recently I would have done it no differently. But PHP 5.3.2 is much better than 5.3.0 and 5.3.1 and offers new features that matter&mdash; improved memory management, faster performance and new PHP language features that the forthcoming Symfony 2.0 requires. Hopefully PHP 5.3.x will appear in the Web Platform installer soon.</p>
<p>(*) Yes, I sorted through the maze and found versions of PHP and APC that were supposedly for the same C runtime, et cetera. Still no love. xcache was better, but alas the redefined class errors put paid to that too.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/04/26/faster-windows-php-kill-kill/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Open Source Help Desk</title>
		<link>http://window.punkave.com/2010/04/14/open-source-help-desk/</link>
		<comments>http://window.punkave.com/2010/04/14/open-source-help-desk/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 14:00:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1103</guid>
		<description><![CDATA[TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;
CALLER: &#8220;I chose your open source project for my client project and it&#8217;s due tomorrow and it doesn&#8217;t work! This is your problem and you must fix it immediately or I will explode!&#8221;
TOM: [CLICK]

TOM: &#8220;Open source help desk, this is Tom [...]]]></description>
			<content:encoded><![CDATA[<p>TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;I chose your open source project for my client project and it&#8217;s due tomorrow and it doesn&#8217;t work! This is your problem and you must fix it immediately or I will explode!&#8221;</p>
<p>TOM: [CLICK]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;Your code has several bugs, which I am going to describe in harsh and unsympathetic but highly accurate detail.&#8221;</p>
<p>TOM: [Hangs up on caller, then fixes those bugs]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;I translated your program into Swahili! Here&#8217;s the XLIFF file. Also I found a bug. Here&#8217;s a patch file.&#8221;</p>
<p>TOM: &#8220;Yay! Welcome to the cool people&#8217;s club! We&#8217;re having chocolate ice cream. Would you like some?&#8221;</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;500 ERROR! AAAAAAAAAAAAAA!&#8221;</p>
<p>TOM: &#8220;Lower your voice, read your log files, try the dev controller and call back.&#8221;</p>
<p>CALLER: [reads own log files, discovers glaringly obvious permissions problem, solves it, is never heard from again]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;something isn&#8217;t quite right. When I do X, Y and Z, I get the following error message [copies and pastes complete error message].&#8221;</p>
<p>TOM: &#8220;reproducible bug reports make me deeply happy. I&#8217;ve just committed a fix in svn. Would you like some ice cream?&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/04/14/open-source-help-desk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Philly Symfony Users Group: ASSEMBLE!</title>
		<link>http://window.punkave.com/2010/03/25/philly-symfony-users-group-assemble/</link>
		<comments>http://window.punkave.com/2010/03/25/philly-symfony-users-group-assemble/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 19:49:58 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1082</guid>
		<description><![CDATA[
Sure, geeks have grabbed Philly by the balls, but that doesn&#8217;t mean we can&#8217;t sharpen our&#8230; skills&#8230; where am I going with this?
Oh yeah: the Philly Symfony Users Group. We use the Symfony framework for PHP development all day long. It&#8217;s been the basis for every single client project we&#8217;ve done since&#8230; hell, before I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://window.punkave.com/2010/03/25/philly-symfony-users-group-assemble/philly-symfony-awesome/" rel="attachment wp-att-1085"><img src="http://window.punkave.com/wp-content/uploads/2010/03/philly-symfony-awesome.png" alt="" title="philly-symfony-awesome" width="293" height="500" class="alignnone size-full wp-image-1085" /></a><br />
Sure, <a href="http://technicallyphilly.com/2010/03/15/philly-invades-south-by-southwest">geeks have grabbed Philly by the balls</a>, but that doesn&#8217;t mean we can&#8217;t sharpen our&#8230; skills&#8230; where am I going with this?</p>
<p>Oh yeah: the Philly Symfony Users Group. We use the <a href="http://www.symfony-project.org/">Symfony</a> framework for PHP development all day long. It&#8217;s been the basis for every single client project we&#8217;ve done since&#8230; hell, before I came aboard two years ago. It&#8217;s the foundation on which <a href="http://www.apostrophenow.com/">Apostrophe</a> is based. We cannot imagine suffering through web application development without it (or at least something on a similar plane of object-oriented, thoroughly modern, Model-View-Controller awesome, like Zend Framework). </p>
<p>But we haven&#8217;t met a lot of other Philly-based Symfony developers. And this is where you come in. We&#8217;d like to spread the word and help aspiring local Symfony developers get their boots on the ground. And if other experienced Symfony developers are out there reading this, we&#8217;d really, <em>really</em> like to get to know you better.</p>
<p>Announcing the Philly Symfony Users Group! Every second Thursday of the month at 6:30pm, you are cordially invited to our office at 1168 East Passyunk Avenue. We&#8217;ll start off with informal discussion (and beer), then someone will present on an aspect of Symfony development.</p>
<p>WHERE: 1168 E. Passyunk Ave<br />
WHEN: 6:30pm, Thursday April 8th<br />
WHAT: Symfony Users Group<br />
PRESENTATION: &#8220;Getting Started with Symfony,&#8221; Tom Boutell</p>
<p>At this first meeting I&#8217;ll talk about the process of installing Symfony, PHP and Apache on your own computer, focusing primarily on what it&#8217;s like to build a simple Symfony 1.4 web application. </p>
<p>You don&#8217;t have to be an experienced Symfony developer to attend! We welcome all PHP developers and those who aspire to become PHP coders. </p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/25/philly-symfony-users-group-assemble/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Apostrophe Speaks Your Language</title>
		<link>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/</link>
		<comments>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 00:18:52 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1076</guid>
		<description><![CDATA[
We&#8217;ve just released version 1.0.9 of Apostrophe, our content management system. This is an exciting release because it includes French, German and Spanish user interfaces, as well as improved support for translating the actual content of your site into multiple languages.
If you visit our demo site and switch languages you&#8217;ll see pages with pretty translated [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/screen-shot-2010-03-24-at-8-13-52-pm/" rel="attachment wp-att-1077"><img src="http://window.punkave.com/wp-content/uploads/2010/03/Screen-shot-2010-03-24-at-8.13.52-PM.png" alt="Apostrophe en francais" title="Apostrophe en francais" width="377" height="218" class="alignnone size-full wp-image-1077" /></a><br />
We&#8217;ve just released version 1.0.9 of <a href="http://www.apostrophenow.com/">Apostrophe</a>, our content management system. This is an exciting release because it includes French, German and Spanish user interfaces, as well as improved support for translating the actual content of your site into multiple languages.</p>
<p>If you <a href="http://demo.apostrophenow.com/">visit our demo site</a> and switch languages you&#8217;ll see pages with pretty translated chrome but no content. That, of course, is because our own demonstration web site&#8217;s content is currently only available in English. Feel free to play with translating it, but keep in mind that the demo site resets at the top of the hour. If you&#8217;re seriously interested in translating our demo site&#8217;s content to go along with the nicely translated interface, <a href="http://groups.google.com/group/apostrophenow">join the Apostrophe google group</a> and drop us a line to get involved.</p>
<p>Interested in putting this power to work on your projects? Visit <a href="http://www.apostrophenow.com/">apostrophenow.com</a> to find out how we can help you. If you&#8217;re a Symfony developer or just a ballsy webmaster who doesn&#8217;t mind learning some new tricks, head straight for the <a href="http://trac.apostrophenow.org/wiki/ManualOverview">Apostrophe manual</a> to check out our installation guide. We do documentation in a big way.</p>
<p>We&#8217;d like to thank Quentin Dugauthier (French), Frank Wenzl (German), and Pablo Godel (Spanish) for their hard volunteer work on the translations. Others are working hard on Portuguese and Greek and have been patient through our growing pains as we mastered the fine points of UTF-8 and character sets in our translation system. We&#8217;ll be sure to thank them by name when they are done, so you don&#8217;t nag them too much now. (:</p>
<hr />
<p>There are, of course, other important fixes and improvements in Apostrophe 1.0.9, including one security fix. Here&#8217;s the list:</p>
<ul>
<li>A computer abandoned by an admin who has logged out can no longer be used to edit slots the admin previously edited using cleverly constructed URLs (only an issue on the same computer and if the PHP session has not ended). Note that you must upgrade your myUser class in apps/frontend/lib to extend aSecurityUser rather than sfGuardSecurityUser to get this fix (aSecurityUser is a subclass of the latter)</li>
<li>Global or virtual-page media slots can be edited successfully on Symfony pages that are not CMS pages</li>
<li>Unpublished pages no longer interfere with aNavigationAccordion layout</li>
<li>Fixtures no longer use HTML tags our filters remove on edit</li>
<li>Plaintext slots now autolink URLs and email address (obfuscated) as described in the manual</li>
<li>Search engine updates refactored, search engine now updates when you save page settings</li>
<li>&#8216;tool&#8217; option to rich text slots now correctly activates the FCK toolbar set name you specify</li>
<li>Slot save/cancel buttons now survive form validation passes properly (thanks to Spike)</li>
<li>Date widget is XHTML correct (thanks Spike)</li>
<li>Engines now work when the CMS is not mounted at the root of the site (important for those using the CMS as a subfolder of a site dominated by other Symfony modules)</li>
<li>Attempting to attach a list of zero items to a slideshow no longer results in adding all items in the media repository</li>
<li>Cross-browser and XHTML strictness fixes</li>
<li>Moved lib/base to lib/action (you must symfony cc)</li>
<li>Lost connections between existing media slots and media items when editing other media slots: fixed. Also, slideshows etc. are no longer removed on &#8220;cancel,&#8221; and selecting zero media items no longer selects all media items</li>
<li>i18n of over 99% of the admin interface (many thanks to Quentin, Galileo, Frank, Pablo and Fotis), new languages are regularly being added to the demo project&#8217;s apps/frontend/i18n folder</li>
<li>More convenient i18n of your site content (temporary titles supplied, all navigation controls work for pages whose titles are not yet translated)</li>
<li>Aesthetic upgrades</li>
<li>Superadmins can grant superadmin status</li>
<li>Some demo-specific styles moved from a.css to demo.css</li>
<li>Optional language selector in a/login partial</li>
<li>Global admin buttons now have separate names and labels (labels can be internationalized) and a documented way to add and reorder them in app.yml</li>
<li>Alpha channel is now preserved when rendering PNGs from a PNG original with gd (not available with netpbm)</li>
<li>Compact PDF slot style, without inline preview (you can override this in aMediaPDF/normalView if you want it back and you have ghostscript)</li>
<li>Better IE6 upgrade message</li>
<li>Various private methods now protected for easier app level overrides</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Faster, PHP! Kill! Kill!</title>
		<link>http://window.punkave.com/2010/03/08/faster-php-kill-kill/</link>
		<comments>http://window.punkave.com/2010/03/08/faster-php-kill-kill/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:39:41 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1029</guid>
		<description><![CDATA[
PHP is easy&#8230; as programming languages go, that is. You can build sites in a real hurry. 
With frameworks like Symfony, you can build them faster still, and follow modern programming practices at the same time. 
And Apostrophe strips away yet another layer of effort if your site calls for a content management system.
Yes, Java [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://window.punkave.com/wp-content/uploads/2010/03/Screen-shot-2010-03-08-at-11.04.17-PM.png" alt="" title="Screen shot 2010-03-08 at 11.04.17 PM" width="216" height="284" class="alignnone size-full wp-image-1036" /><br />
PHP is easy&#8230; as programming languages go, that is. You can build sites in a real hurry. </p>
<p>With frameworks like <a href="http://www.symfony-project.org/">Symfony</a>, you can build them faster still, and follow modern programming practices at the same time. </p>
<p>And <a href="http://www.apostrophenow.com/">Apostrophe</a> strips away yet another layer of effort if your site calls for a content management system.</p>
<p>Yes, Java has more raw speed, all else being equal (which it never is). But as the LISP programmers used to say, &#8220;a moment of regret, a lifetime of convenience.&#8221;</p>
<p>Still, sooner or later success catches up with you and you want your site to cope with Serious Traffic&#8230; or cope with moderate traffic on a cheap virtual machine&#8230; or at the very least, not be dog-slow with just a handful of users on the system.</p>
<p>There&#8217;s a lot of advice out there about optimizing PHP code, some of it well worth your while. And there&#8217;s excitement about HipHop, Facebook&#8217;s new native code compiler for PHP. But these are drastic steps that require you to rewrite your code or adopt less proven and more awkward ways of delivering your code. </p>
<p>Justified? Sure, sometimes, on the biggest projects in the world (like Facebook) (*). But as Donald Knuth says, &#8220;premature optimization is the root of all evil.&#8221; That&#8217;s because tweaking your code for speed&#8217;s sake usually makes it harder to maintain and less adaptable to new requirements.</p>
<p>What most developers don&#8217;t realize is that there are three major factors that typically slow down PHP projects based on frameworks (like Symfony or, <em>sigh</em>, Drupal) so much that code profiling and database query redesign don&#8217;t even have a chance to become relevant factors. Fix these things first before you worry about other issues:</p>
<p><strong>1. Compiling code over and over and over.</strong> Would you wait for your Mac to recompile MacOS X from source code every time you boot it up? Of course not. How about every time you fill out a dialog box? That&#8217;s pretty much what you&#8217;re doing every time you access a PHP-driven website that doesn&#8217;t use a bytecode cache.</p>
<p><strong>2. Waiting and waiting and waiting for web browsers to make another request,</strong> pinning down web server processes that your other users need. By default Apache usually lets browsers hold on to a connection for up to 15 seconds just in case they ask for more. This is a good thing in many ways, but 15 seconds is far too long. Which leads us to #3:</p>
<p><strong>3. Tying up a &#8220;fat&#8221; web server process with PHP on board for every request,</strong> even requests for the zillions of little static PNGs that probably make up your page design. (**)  A typical Apache web server configuration with <tt>mod_php</tt> suffers from this flaw, fatally limiting the number of simultaneous users you can handle. </p>
<p>So what can we do about these problems? Quite a bit as it turns out. I&#8217;ll start with the low-hanging fruit and move on to the tougher stuff. The fascinating common thread with all of these suggestions: no changes at all to your PHP code.</p>
<p><span id="more-1029"></span></p>
<h2>Stop Recompiling Your World: APC</h2>
<p>APC, aka the Alternative PHP Cache, is a bytecode cache. What does that mean and what good does it do?</p>
<p>Today, when users visit your website, your web server struggles to translate all of your PHP code into a more manageable &#8220;bytecode.&#8221; And only then does it actually run the bytecode and output the page.</p>
<p>Bytecode isn&#8217;t true native machine code and doesn&#8217;t run as fast as compiled Java, and certainly not as fast as compiled C. That&#8217;s why Facebook&#8217;s HipHop project seeks to convert PHP code to C++, and then compile that to native code. But that&#8217;s a drastic step with far-reaching consequences for your project. Before you think about HipHop, try a simpler fix: stop throwing away the bytecode and starting over from zero on every new request that comes to the site! </p>
<p>In our experience, enabling APC reduces both memory usage and the time required to respond to a request by vast amounts. Even a simple action in Symfony or Drupal can implicitly require that quite a bit of PHP code be compiled. With APC, all of that code <i>stays</i> compiled, and that simple action actually runs quickly and simply. </p>
<p>APC is simply indispensable for serious PHP programming. Turn it on. Make sure it&#8217;s really working. And enjoy dramatic improvements in your social life, hair and skin.</p>
<h3>Installing APC</h3>
<p>Depending on your system, APC may already be installed or even, if you are very lucky, activated correctly. Virtual machine hosting from <a href="http://www.servergrove.com/">ServerGrove</a> comes with APC &#8220;out of the box.&#8221; Most shared hosting probably won&#8217;t because it increases the amount of memory pinned down for each user on the shared server, but if you care about your website&#8217;s speed, you&#8217;re not using shared hosting. Get a small, cheap virtual machine from ServerGrove instead (or if you must, do it the hard way and set up a Slicehost or linode virtual machine; you&#8217;ll learn a lot about system administration).</p>
<p>On our slicehost VMs, we found it necessary to install APC with pecl, the PHP package manager for extensions (like PEAR, but different in that they are not written in plain PHP):</p>
<pre>
pecl install apc
</pre>
<p>We then enable it in php.ini (you won&#8217;t be able to do this in a .htaccess file):</p>
<pre>
; Must enable APC otherwise we compile all of Symfony on every hit
extension=apc.so
; Give APC enough shared memory to handle Symfony, etc.
apc.shm_size = 48
apc.include_once_override = 1
apc.mmap_file_mask = /tmp/apc.XXXXXX
</pre>
<p>Then restart Apache:</p>
<pre>
apachectl restart
</pre>
<p>And you&#8217;re off to the races. The first page access will be as slow as ever, but subsequent accesses will be much, much faster. You can also check whether you&#8217;re saving memory and time using Symfony&#8217;s debugging toolbar. </p>
<p>Your system also likely has an <a href="http://www.electrictoolbox.com/apc-php-cache-information/">APC status page</a> that you can copy to your website to check out the current status of APC. It&#8217;s fun to play with.</p>
<h2>Dialing Back Keepalive: Too Much of a Good Thing</h2>
<p>In the beginning there was NCSA Mosaic, and it was pretty cool, all things considered. But it wasn&#8217;t fast.</p>
<p>Mosaic made only one request of a web server at a time. Trying to do more probably seemed rude. Besides, lots of web servers couldn&#8217;t cope with more than one request a time <i>at all</i>. But that would only happen if two users came along at once, and that was never gonna happen, right? </p>
<p>Ah, those were the (sad, lame, pathetic) days. Scroll to the present. Typical web browsers first request the page, say &#8220;hang on a minute,&#8221; open perhaps five <em>more</em> connections besides and then make note of all the images, JavaScript files, CSS files and other embedded bric-a-brac and start requesting all of those things. Consecutively and in parallel. Really a lot.</p>
<p>The Apache web server is actually very good at handling this. But by default, it is very generous: it lets the browser leave it hangin&#8217; for fifteen seconds. That means an Apache process and all of the memory it requires is tied up for all of that time, just doin&#8217; nothin&#8217;. And that&#8217;s bad news.</p>
<p>Fortunately it&#8217;s very easy to fix this in your <code>httpd.conf</code> file (actually, in our setups, this is usually in <code>apache2.conf</code>):</p>
<pre>
KeepAliveTimeout 2
</pre>
<p>Restart Apache:</p>
<pre>
apachectl restart
</pre>
<p>And you&#8217;ll find that your site can suddenly cope with higher loads. That&#8217;s because your&#8217;re not tying up valuable resources waiting around for more requests from browsers that are <i>already</i> using and reusing five other connections to your server. The browser is welcome to promptly request more files and finish its business with you, but not to stand around twiddling its thumbs while you wonder if you have a date or not.</p>
<p>You can turn keepalive off entirely, but doing so forces the browser to &#8220;call back&#8221; for each and every little image file on your page, which is a terrible idea. So use it&#8230; just don&#8217;t let it abuse you.</p>
<h2>MaxClients: Does This <code>mod_php</code> Make My Butt Look Big?</h2>
<p><code>mod_php</code> is fast. Unlike the old-fashioned &#8220;PHP as CGI&#8221; approach, <code>mod_php</code> keeps the PHP interpreter itself loaded in memory and ready to rock at all times, and that&#8217;s good.</p>
<p>But <code>mod_php</code> is also a pig. For a big-deal web application that wrangles lots of database objects, or makes thumbnails of uploaded images, or does pretty much anything cool, it&#8217;s not uncommon for a PHP process to use 50MB of memory or more. More miserly code can still hit 30MB without much difficulty.</p>
<p>We first ran into this problem when we wanted to move smaller client sites onto small VMs, so that they could have well-secured, highly-reliable web hosting at an affordable price. They tended to bog down and become unusable quickly.</p>
<p>We discovered that dialing back keepalive helped tremendously with the problem. And we also learned to do the math and figure out how many reasonably fat PHP Apache processes would really fit in the memory available to the slice, and configure Apache to run no more than that. In <code>httpd.conf</code>:</p>
<pre>
MaxClients          20
</pre>
<p>This may seem drastic (OMG! I can&#8217;t serve more than 20 simultaneous users!) but here&#8217;s the thing: you already can&#8217;t. If you try, if you leave this set to its much higher default, the result will be a VM crushed by the need to swap out all of these Apache processes to virtual memory while they are still trying to do work. As the operating systems geeks say, the &#8220;resident set size&#8221; of your Apache and PHP processes is bigger than your actual memory. And when that happens you&#8217;re SOL.</p>
<p>When you set MaxClients to a realistic number, what happens instead is this:</p>
<p><em>You can handle up to 20 connections at once gracefully.<br />
That 21st connection queues up and is dealt with soon after.<br />
If the average load doesn&#8217;t exceed 20 connections, you&#8217;re fine.</em></p>
<p>If too many connections queue up, some people will not get through. But <em>you</em> will still be able to get through to other services on the VM&#8230; like the ssh connection you use to administer it and change these settings. Without that, you&#8217;re stuck in a seesaw battle, shutting down your website, tweaking settings, firing it up again and watching it gradually become overwhelmed.</p>
<h3>What Is The Right MaxClients For Me?</h3>
<p>Take the amount of RAM in your server (for instance, a 256MB slicehost VM). Subtract a bit of overhead (at least 50MB, ideally more, bigger VMs are better that way). Now divide by the largest PHP process you typically see when running &#8220;top&#8221; or &#8220;ps -auxw | grep httpd&#8221; (you might have to grep for apache rather than httpd depending on your OS). For instance, if your processes top off around 30MB, you can set MaxClients to (256-30) divided by 30. Round down and you have a MaxClients setting of 7.</p>
<p>One snag: some operating systems show shared memory (like the memory used by APC) as memory in use by every one of the Apache processes, even though it is really only allocated once and shared by all of them. If your APC cache is set to 40MB and all of your PHP processes seem 40MB overweight, you can increase MaxClients somewhat to allow for this.</p>
<p>Yes, you can use swap space (virtual memory) to go higher, but this just forces the machine to swap, using disk space in place of memory to do hard things it needs to do quickly and freezing you out of your own machine. So don&#8217;t do that.</p>
<h2>PHP, I Love You, But Could You Sleep Downstairs?</h2>
<p>Dialing back the number of Apache processes is a helpful step that allows your server to say no with grace and style when there is too much traffic. But the underlying problem remains: we can&#8217;t deal with a lot of requests at once. And the reason we can&#8217;t do that is PHP. So we&#8217;re stuck. Or are we?</p>
<p>Our Apache processes are &#8220;fat&#8221; in terms of memory use because of the memory taken up by PHP. But most of the requests we&#8217;re handling are for little PNG files and not-so-little JPEG files and CSS files and JavaScript files&#8230; all of which Apache can serve up handily with about three bytes of memory and a piece of string. </p>
<p>The obvious solution is to serve PHP requests and static files separately. And many sites do this explicitly, using absolute URLs pointing at a different subdomain for static files. For example:</p>
<p>&lt;img src=&#8221;http://static.example.com/foo.png&#8221; /&gt;</p>
<p>Now, this is a fine thing and I have nothing against it. When you design things this way you can use entirely separate machines to serve these requests if you wish, and that&#8217;s pretty exciting from a performance perspective. Many bigger sites find this well worth their while.</p>
<p>But you are also complicating things. And you are forced to change working code, which introduces the potential for new and exciting bugs.</p>
<p>There&#8217;s another approach (well, one of many): FastCGI. FastCGI is an enhanced version of the CGI protocol that appeared quite early in the evolution of the web but caught on only with those most concerned about performance. I must admit I am a very recent convert, ironic since FastCGI is a bit out of vogue today. But there are solid reasons to consider using it.</p>
<p>FastCGI has three big advantages:</p>
<p>1. FastCGI runs PHP processes separately from Apache. That means Apache can stay lean and mean, not only running much smaller processes (and therefore perhaps many more of them) but even running in a separate &#8220;worker thread&#8221; that outperforms the separate-processes mode by a long mile. This is a big, big win.</p>
<p>2. It can reuse a single process for new PHP requests (***), avoiding the need to restart the PHP interpreter. That&#8217;s nice, but mod_php can do the same trick, and mod_php is capable of sharing APC cache memory between all of its processes. And FastCGI can&#8217;t do that&#8230; or it wouldn&#8217;t be able to without a little help from PHP:</p>
<p>3. PHP comes with a special FastCGI mode in which it manages several child processes of its own, and <strong>allows all of those processes to share a single APC cache.</strong> </p>
<p>Put these advantages together and you have the holy grail of PHP hosting: PHP running separately from Apache, but still maintaining all of the performance advantages of the APC cache. And we can do it without changing a line of PHP.</p>
<h3>Installing FastCGI</h3>
<p>There&#8217;s one catch: Apache 2.0 ships with <code>mod_cgid</code>, a rewritten version of FastCGI that complies with the official Apache license, instead of the oh-so-fractionally-different FastCGI license (****). And it&#8217;s nice and all, except that it completely lacks the third advantage of FastCGI I mentioned above. If you want the benefits I&#8217;m describing here, you have to use the real <code>mod_fastcgi</code>. Accept no substitutes.</p>
<p>These directions work for slicehost Ubuntu slices and other Ubuntu-based Linux. They will not work exactly as-is for servergrove which is centos-based:</p>
<p>Edit /etc/apt/sources.list<br />
Add multiverse, which includes software with insufficiently &#8220;open&#8221; licenses, such as mod_fastcgi. Change intrepid to the ubuntu version on your box, it&#8217;ll be mentioned all over sources.list:</p>
<pre>
# tom@punkave.com: we want multiverse support so we can have real mod_fastcgi
deb http://us.archive.ubuntu.com/ubuntu/ intrepid multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ intrepid multiverse
deb http://us.archive.ubuntu.com/ubuntu/ intrepid-updates multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ intrepid-updates multiverse
</pre>
<p>Now do:</p>
<pre>
apt-get update
apt-get install libapache2-mod-fastcgi
</pre>
<p>Now edit /etc/apache2/mods-available/fastcgi.conf to read:</p>
<pre>
&lt;IfModule mod_fastcgi.c&gt;
  # One shared PHP-managed fastcgi for all sites
  Alias /fcgi /var/local/fcgi
  # IMPORTANT: without this we get more than one instance
  # of our wrapper, which itself spawns 20 PHP processes, so
  # that would be Bad (tm)
  FastCgiConfig -idle-timeout 20 -maxClassProcesses 1
  &lt;Directory /var/local/fcgi&gt;
    # Use the + so we don't clobber other options that
    # may be needed. You might want FollowSymLinks here
    Options +ExecCGI
  &lt;/Directory&gt;
  AddType application/x-httpd-php5 .php
  AddHandler fastcgi-script .fcgi
  Action application/x-httpd-php5 /fcgi/php-cgi-wrapper.fcgi
&lt;/IfModule&gt;
</pre>
<p>Now set up /var/local/fcgi/php-cgi-wrapper.fcgi:</p>
<pre>
mkdir -p /var/local/fcgi/
vi /var/local/fcgi/php-cgi-wrapper.fcgi
</pre>
<p>Paste in:</p>
<pre>
#!/bin/sh

# We like to use the same settings we formerly used for apache mod_php.
# You don't want this if your php.ini is in /etc
PHPRC="/etc/php5/apache2"
export PHPRC
# We can accommodate about 20 50mb processes on a 1GB slice. More than that
# will swap, making people wait and locking us out of our own box.
# Better idea: just make people wait to begin with
PHP_FCGI_CHILDREN=20
export PHP_FCGI_CHILDREN
exec /usr/bin/php-cgi
</pre>
<p>Note the figure 20, this can be adjusted for the box in question if it has more or less memory to offer. Also note that we use the same php.ini we used with mod_php (/etc/php5/apache2). You can change that if you think it appropriate but don&#8217;t forget to bring settings over.</p>
<p>Set permissions:</p>
<pre>
chmod -R 755 /var/local/fcgi
</pre>
<p>IMPORTANT: comment out any php_value lines in .htaccess files for the sites on this box, and move those directives to php.ini. Otherwise you will get errors form those sites and they won&#8217;t work. </p>
<p>If two sites on the same slice really must have separate php.ini settings, consider separate slices for the sites. It&#8217;s possible to set up more than one fastcgi pool, but that halves the resources available and so on.</p>
<pre>
# Commented out; moved to /etc/php/apache2/php.ini
# php_value arg_separator.output &#038;
</pre>
<p>Disable mod_php5, enable mod_fastcgi in its place, enable mod_actions which is required by the above, and restart Apache:</p>
<pre>
a2dismod php5; a2enmod fastcgi; a2enmod actions; apache2ctl restart
</pre>
<p>Now test the site. Also check /var/log/error.log and/or error.logs for individual sites to make sure you see mentions of fastcgi and not mod_php.</p>
<p>If you get an error and you see this in the log:</p>
<pre>
[Thu Mar 04 02:51:33 2010] [alert] [client 69.141.215.7] (2)No such file or directory: FastCGI: failed to connect to (dynamic) server "/var/local/fcgi/php-cgi-wrapper.fcgi": something is seriously wrong, any chance the socket/named_pipe directory was removed?, see the FastCgiIpcDir directive
</pre>
<p>There&#8217;s a chance it&#8217;s just a transitory problem; first-time fastcgi startups seem to be a bit temperamental, but we&#8217;ve had no problems in the long haul. Restart apache again:</p>
<pre>
apache2ctl restart
</pre>
<p>If it still doesn&#8217;t work reenable mod_php5:</p>
<pre>
a2dismod fastcgi; a2enmod php5; apache2ctl restart
</pre>
<p>And do some more reading.</p>
<h3>Late-breaking news: PHP 5.3.3 and the new SAPI FPM</h3>
<p>In addition to the built-in support for managing FastCGI child processes in php-cgi, PHP 5.3.3 introduces a new PHP binary, php-fpm, that offers a superior implementation of FastCGI support. You don&#8217;t have to switch if you are happy with the FastCGI support in php-cgi, which is fortunate because your operating system might not offer PHP 5.3.3 or its new php-fpm binary (aka the SAPI FPM) yet.</p>
<p>Setting up the new SAPI is not that different from setting up FastCGI with php-cgi, provided you can get past the probable need to compile it yourself (of course, by the time you read this, there may be a php-fpm package in your favorite Debian repository).</p>
<p>Interested parties should <a href="http://www.php.net/manual/en/install.fpm.php">check out the new FastCGI Process Manager article on www.php.net</a>.</p>
<h3>Installing the Worker Thread MPM</h3>
<p>Once you reach this point successfully, you are ready to switch Apache from &#8220;prefork&#8221; mode (which mod_php requires) to &#8220;worker thread&#8221; mode. Worker thread mode is blindingly, ri<em>dun</em>culously fast at serving static stuff, and uses mod_fastcgi to take care of PHP. You can&#8217;t do this with mod_php enabled, so you must succeed in setting up fastcgi first (see above):</p>
<pre>
apt-get install apache2-mpm-worker
</pre>
<p>That will restart Apache by itself. But if not you can do so manually.</p>
<p>Now test the site again. If it doesn&#8217;t work, you can easily undo this:</p>
<pre>
apt-get install apache2-mpm-prefork
</pre>
<p>To verify success:</p>
<pre>
ps auxw | grep apache
</pre>
<p>Should show fewer processes (unless your operating system shows threads as processes). The processes you do have are running many threads (lightweight subprocesses that are exposed to each other&#8217;s memory etc. and generally less expensive).</p>
<p>ps auxw | grep php</p>
<p>Should show roughly 20 processes, plus a process to manage the others. Significantly more than 20 (say, 40+) indicates you goofed and didn&#8217;t set maxClassProcesses properly and you&#8217;re going to have a lot of PHP processes on your hands in a hurry, so fix that. (I&#8217;m assuming you chose 20 processes as your limit for PHP above.)</p>
<p>Now beat up on the site a bit. Remember to check any other sites on the same box, you just changed how all of your PHP sites on this box are run. </p>
<p>Now copy apc.php to the web folder of one of your sites and visit that URL to see a page giving stats about how well the cache is working. You should see a healthy percentage of cache hits if you have revisited some of the same pages or at least reused Symfony and Doctrine. If not check whether you ever enabled APC for this site. You can find apc.php in /usr/share/php/apc.php on some systems. Its absence doesn&#8217;t mean APC is not available.</p>
<p>You need to set up both mpm-worker and fastcgi to get the most benefit here. The worker MPM can serve zillions of static files in a hurry with minimal memory usage each. However, after setting up fastcgi, you can certainly crank up MaxClients and stick with the prefork MPM if you prefer.</p>
<h2>Alternatives</h2>
<p><strong>APC alternatives:</strong> there are alternatives to the APC cache. These include eAccelerator and Zend Optimizer. I&#8217;m not an expert on the others, but APC will be standard in PHP 6.0, so I recommend standardizing on it now. For extreme cases (i.e. &#8220;we&#8217;re getting as big as Facebook and we have too much code to start thinking about improving the code itself in any serious way&#8221;), by all means consider <a href="http://wiki.github.com/facebook/hiphop-php/">HipHop</a>. You can think of it as a distant relative of APC that provides a roughly 2x performance boost at a large cost in complexity and maintenance.</p>
<p><strong>FastCGI alternatives:</strong> some will disagree with my recommendation of FastCGI. mod_cgid supposedly has better child process management&#8230; with the glaring exception that APC is not shared, ballooning your memory requirements in a seriously ugly way. Better alternatives include running the <a href="http://nginx.org/en/">nginx</a> (pronounced &#8220;engine X&#8221;) web server as a lightweight &#8220;front end&#8221; that serves static files directly and proxies other requests through to an Apache server running mod_php. One can also run Apache (without the fat mod_php module) as a front end for another instance of Apache. In these setups, the back-end Apache doesn&#8217;t accept connections except from the front-end one, and Apache&#8217;s reverse proxy features come into play. Personally I like the simplicity of Apache communicating directly with a master PHP process via the FastCGI protocol.</p>
<h2>Conclusion</h2>
<p>ERRRRRRRRRRRROOOOOMMMMMMM</p>
<p>Beep beep</p>
<p>ERRRRRRRRRRRRRRRRRROOMMMMMMMM</p>
<p>[HONK]</p>
<p>Zoom!</p>
<p>(*) Actually, one of Facebook&#8217;s stated goals for HipHop is to avoid rewriting and presumably hand-optimizing their existing PHP code. They have billyuns and billyuns of lines of PHP code, not all of it written by hardcore software jocks. So if a handful of smart folks can make mediocre PHP run 50% faster, that&#8217;s a big deal for Facebook. For most of us it makes more sense to pick the low-hanging fruit first (see all of the above), and then stop making separate SQL queries for every single darn object on the page, and <em>then</em> maybe think about HipHop. I&#8217;m not knocking HipHop here at all, it&#8217;s an impressive technical accomplishment. But if you&#8217;re starting with HipHop as your<br />
first optimization, you&#8217;re not paying attention.</p>
<p>(**) Yes, you could use CSS sprites to speed these up, and given time you probably should, but in the short term let&#8217;s talk about ways to deliver them quickly without getting bogged down in hard-to-maintain optimizations. With HTTP keepalive working for us instead of against us, the performance difference between delivering 20 PNGs and one PNG is mostly on the browser side&mdash; still good to avoid, but not a brutal impact on your web server. One step at a time, okay?</p>
<p>(***) Yes, FastCGI is capable of running lots of things other than PHP, but this is a PHP article. So: neener.</p>
<p>(****) There&#8217;s nothing wrong with the FastCGI license. It&#8217;s <a href="http://www.fastcgi.com/devkit/LICENSE.TERMS">a very boring MIT-style license</a> that shouldn&#8217;t interfere with your commercial use.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/08/faster-php-kill-kill/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Choice is a good thing</title>
		<link>http://window.punkave.com/2010/02/24/choice-is-a-good-thing/</link>
		<comments>http://window.punkave.com/2010/02/24/choice-is-a-good-thing/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 22:55:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1027</guid>
		<description><![CDATA[Just a quick note in response to Lukas Kahwe Smith&#8217;s recent comments about the &#8220;problem&#8221; of multiple CMSes for Symfony. This note began as a comment of mine on Lukas&#8217; blog.
We developed Apostrophe to scratch our own itch: we needed a CMS that our clients could use to add content to their sites in a [...]]]></description>
			<content:encoded><![CDATA[<p><i>Just a quick note in response to <a href="http://pooteeweet.org/blog/1674">Lukas Kahwe Smith&#8217;s recent comments about the &#8220;problem&#8221; of multiple CMSes for Symfony</a>. This note began as a comment of mine on Lukas&#8217; blog.</i></p>
<p>We developed <a href="http://www.apostrophenow.com/">Apostrophe</a> to scratch our own itch: we needed a CMS that our clients could use to add content to their sites in a variety of ways without inadvertently breaking the site design. So our CMS concentrates on the admin&#8217;s user experience, extending metaphors already present in the page. It&#8217;s about design even more than it&#8217;s about software architecture.</p>
<p>We also wanted to make sure it supported Symfony coding practices we were already having good success with. Therefore slots and engines implemented as Symfony modules, not new abstractions, and a clear lineage back to ideas from sfSimpleCMS.</p>
<p>We open sourced Apostrophe because we saw a win-win situation: other developers are in the same boat (their clients are also frustrated with Drupal administration, and they need a good solution today).</p>
<p>More eyes on our code, more bug reports, more suggestions equals a better system for everyone in the Apostrophe community.</p>
<p>Right now this is working for us in a big way, and it&#8217;s running in production on a number of client sites. Others on the <a href="http://groups.google.com/group/apostrophenow">apostrophenow google group</a> are also happy with it (although they have valid criticisms that we are addressing), and they are building client sites that work. There&#8217;s no business case for us to screech to a stop and start doing something radically different.</p>
<p>Right now we have a team of seven people doing great work with Apostrophe and no interest in stopping that. Evolving it to be better, eventually rewriting it extensively in the Symfony 2.0 timeframe&#8230; sure! But unless the marketplace tells us otherwise, we&#8217;re going to keep doing good business, writing good code and sharing our work with those who like our approach.</p>
<p>Joomla, Wordpress and Drupal are all thought of as CMSes for PHP, but no one is telling them that they must merge. Why? People pick the project that works best for their needs. That&#8217;s as it should be. Software architecture isn&#8217;t the only differentiating factor between content management systems. </p>
<p>If you like Diem or Sympal&#8217;s approach better, heck, go ahead and use &#8216;em. A &#8220;there can be only one&#8221; approach leads to design by committee, and that is not always a good thing.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/02/24/choice-is-a-good-thing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
