<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
	<title>Recess PHP Framework</title>
	<link>http://www.recessframework.org</link>
	<description>Development Blog of the RECESS! Framework.  RECESS! is an open-source web framework that brings the fun back to PHP.</description>
	<language>en-us</language>
	<copyright>Copryight 2009 Kris Jordan.</copyright>

		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/RecessFramework" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Recess Community Updates</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/B5rrAbpjEGM/recess-community-updates</link>
		<description>&lt;p&gt;In the month since the new Recess Forums have launched the number of posts and interesting topics has been flourishing. Lots of great things are bubbling up:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://forums.recessframework.org/topic/37-postgres/"&gt;PostgreSQL support is being developed on the database stack&lt;/a&gt; lead by Ryan Day. You can pull &lt;a href="http://github.com/rday/recess"&gt;Ryan's postgres bits from Github here&lt;/a&gt;. Ryan has also put up two great, introductory tutorials on his blog. &lt;a href="http://ryanday2.blogspot.com/2009/09/recess-framework.html"&gt;The first is on modifying the generated scaffolding code&lt;/a&gt;. &lt;a href="http://ryanday2.blogspot.com/2009/09/more-recess-beefing-up-date-inputs.html"&gt;The second is on beefing up date input fields&lt;/a&gt;. Awesome work.&lt;/p&gt;
&lt;p&gt;Christiaan has been working on a Recess project that changes the Recess flow-of-control policy to achieve a more nested MVC approach. &lt;a href="http://github.com/christiaan/alive"&gt;Check out his project alive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Issue tracking has moved from lighthouse to &lt;a href="http://github.com/recess/recess/issues"&gt;Github&lt;/a&gt; to keep our source and bugs closer together.&lt;/p&gt;
&lt;p&gt;Some other interesting threads from the forums:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://forums.recessframework.org/topic/33-a-better-description-of-annotations/"&gt;Custom Recess annotation development with examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://forums.recessframework.org/topic/39-complex-boolean-sql-queries/"&gt;API design discussion around complex boolean queries in the Recess ORM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ned Schwartz details the &lt;a href="http://forums.recessframework.org/topic/44-installing-pdo-mysql-drivers-in-os-x-leopard/"&gt;installation of PDO MySQL drivers on OSX Leopard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Feature Request: &lt;a href="http://forums.recessframework.org/topic/52-request-update-and-delete-models/"&gt;Editing and Updating Models/Tables from Recess Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and &lt;a href="http://forums.recessframework.org/index"&gt;lots of other interesting threads...&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you haven't joined the forums or checked back in on them in a while, you should head that way.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/B5rrAbpjEGM" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/recess-community-updates</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/recess-community-updates</feedburner:origLink></item>
		<item>
		<title>Dynamic Invocation in PHP: is_callable, call_user_func, and call_user_func_array - Functional PHP 5.3 Part III</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/Nb8lmPMCn4Q/php-callables-is-callable-call-user-func-array-reflection</link>
		<description>&lt;p&gt;In PHP you can dynamically invoke functions, lambdas, and methods in a number of ways. In this third part of the series we're going to explore &lt;em&gt;callables&lt;/em&gt; in PHP 5.3. Check out Part I of the series if you're unfamiliar with &lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;anonymous functions, lambdas and closures in PHP 5.3&lt;/a&gt;. Part II followed up with a look at &lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;higher order PHP functions by implementing map and reduce&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;What is Dynamic Invocation?&lt;/h2&gt;
&lt;p&gt;We've seen a flavor of dynamic invocation in the previous posts of this series using higher-order methods. The functions map and reduce receive a lambda as an argument and dynamically invoke it at runtime. PHP doesn't know (or care) in advance which lambda it is passed and it won't know until runtime:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;$lambda = rand(0,1) ? function() { echo "Heads!"; } :
                      function() { echo "Tails!"; };
$lambda(); // &amp;lt;= Dynamic Invocation!
&lt;/pre&gt;
&lt;p&gt;It's not until we run the script and flip the coin that PHP will know which anonymous function is being invoked. PHP has actually had the ability to do dynamic invocation for quite some time. Let's take a look at a similar example using code that runs pre- PHP 5.3:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function heads() { echo "Heads!"; }
function tails() { echo "Tails!"; }
$function = rand(0,1) ? 'heads' : 'tails';
$function(); // &amp;lt;= Dynamic Invocation!
&lt;/pre&gt;
&lt;p&gt;We start by defining two functions named heads and tails, respectively. We then flip a coin and assign the string "heads" or "tails" to $function. Finally we invoke $function as if it were a lambda and the correct function gets called! Under its breath PHP is saying "looks like a function call, but this is actually a string whose value is 'heads'. Do I know of a function named 'heads'? Yes! Initiate dynamic invocation thrusters in 5...4...3...2..."&lt;/p&gt;
&lt;p&gt;What if $function's value was a string with no corresponding method name, or an integer, or a boolean? You would murder our friend PHP. You should know that death by dysfunctional dynamic invocation is a most cruel and unusual death.&lt;/p&gt;
&lt;pre name="code" class="php"&gt;$fatality = 'Finish Him!';
$fatality();
// Fatal error: Call to undefined function Finish Him!()
&lt;/pre&gt;
&lt;h2&gt;is_callable to PHP's defense&lt;/h2&gt;
&lt;p&gt;How can you stop yourself from murdering PHP with dysfunctional dynamic invocations? Enter: is_callable. If safety is your concern, is_callable is your defense. Pass any variable you want to is_callable and it will tell you true or false whether or not it can be dynamically invoked.&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function heads() { echo "Heads!"; }
$function = 'heads';
is_callable($function); // true

$lambda = function() { echo "Tails!"; }
is_callable($lambda); // true

$kimJungIl = "fireNukesAndSingAboutLoneliness";
is_callable($kimJungIl); // false
&lt;/pre&gt;
&lt;p&gt;With the powers of is_callable we can learn whether making a dynamic call to the contents of a variable makes sense. Notice that is_callable works on both the function name string variable $function, and the anonymous function $lambda. We can call them just the same, too, so they can be used interchangeably:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function heads() { echo "Heads!"; }
$callable = rand(0,1) ? 'heads' : function() { echo "Tails!"; };
if(is_callable($callable)) {
    $callable();
}&lt;/pre&gt;
&lt;p&gt;This is really sweet because with higher-order functions like map and reduce we can pass either a lambda as demonstrated in part II, or string that is the name of a first-class function, and it will work just the same. &lt;strong&gt;Dynamic invocation enables flexibility through &lt;em&gt;indirection&lt;/em&gt; and &lt;em&gt;late-binding&lt;/em&gt;.&lt;/strong&gt; Now that we've seen dynamic invocations of functions and anonymous functions, what about methods and static methods?&lt;/p&gt;
&lt;h2&gt;Dynamically Invoking Instance and Static Methods&lt;/h2&gt;
&lt;p&gt;While practicing the powers of our ability cast dynamically invocations of methods and lambdas, an elder PHP programmer presents a challenge: dynamically invoke an object's method without our script becoming a statistic, just another PHP fatality. With a mischeivious grin she hints, "Try not with a string, you will. Do with a two element array, you must."&lt;/p&gt;
&lt;pre name="code" class="php"&gt;class Object { 
	function method() { echo "Great success!"; }
}
$callableArray = array(new Object, 'method');
if(is_callable($callableArray)) {
    $callableArray();
}&lt;/pre&gt;
&lt;p&gt;Taking the hint we place an instance of the object as the first element of our array, and the name of the method as the second. We protect ourselves by only commiting to the dynamic invocation if the array is callable. We're safe, &lt;em&gt;right&lt;/em&gt;? So, we run the script... and we murder PHP. &lt;strong&gt;Fatal error: Function name must be a string &lt;/strong&gt;The elder chuckles and walks away...&lt;/p&gt;
&lt;h2&gt;Use &lt;strong&gt;&lt;em&gt;call_user_func&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;&lt;strong&gt;call_user_func_array&lt;/strong&gt;&lt;/em&gt; for Robust Dynamic Invocation in PHP&lt;/h2&gt;
&lt;p&gt;PHP's achilles heel is its inconsitencies. It may never live them down. C'est la vie. It turns out is_callable doesn't mean &lt;em&gt;directly callable&lt;/em&gt;, but rather callable using the utility functions &lt;strong&gt;call_user_func&lt;/strong&gt; or &lt;strong&gt;call_user_func_array&lt;/strong&gt;. Let's try that example again:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;class Object { 
	function method($greatWho, $greatWhat) { 
		echo "$greatWho are Great $greatWhat!";
	}
}
$callableArray = array(new Object, 'method');
if(is_callable($callableArray)) {
    call_user_func($callableArray, "You", "Success");
    call_user_func_array($callableArray, array("You", "Success"));
}&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;"You are Great Success!&lt;/em&gt;" Says the script. Notice the subtle variation in how each is called. &lt;strong&gt;call_user_func&lt;/strong&gt; takes a list of arguments following the $callable just like any other function call, whereas &lt;strong&gt;call_user_func _array&lt;/strong&gt; takes an array that will be used as arguments. In practice this means you can use call_user_func when you know exactly the arguments you want to send to the callable, and call_user_func_array when you don't know how many arguments or when it varies. Can you think of a time when you wouldn't know the exact arguments to use in a dynamic invocation?&lt;/p&gt;
&lt;p&gt;Thought of an example yet? How about if we wanted a generic way to wrap new behavior around a function? A simple example...&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function wrapWithEcho($callable) {
    return function() use ($callable) {
        echo "Calling!";
        call_user_func_array($callable, func_get_args()); // !!!
        echo "Done calling!"; 
	};
}

function aDeliciousFunction($subject) { echo "Mmm, $subject!"; }
$aDeliciousFunction = 'aDeliciousFunction';
$aDeliciousFunction('candy'); 
// Mmm, Candy!
$aDeliciousFunction = wrapWithEcho($aDeliciousFunction);
$aDeliciousFunction('candy');
// Calling! Mmm, Candy! Done Calling!

function anotherDeliciousFunction($subject, $verb) {
	echo "I love to $verb $subject!";
}
$anotherDeliciousFunction = 'anotherDeliciousFunction';
$anotherDeliciousFunction('candy','eat'); 
// I love to eat candy!
$anotherDeliciousFunction = wrapWithEcho($anotherDeliciousFunction);
$anotherDeliciousFunction('candy','unwrap'); 
// Calling! I love to unwrap candy! Done calling!&lt;/pre&gt;
&lt;p&gt;The focal point of this example is near the three bangs (!!!). Our wrapWithEcho function is returning an anonymous function &lt;em&gt;that closes over the callable&lt;/em&gt; and does not know, or care, how many arguments that the callable should be passed. In fact, we wrap two different functions that take two different parameter counts and it all just works! Without &lt;strong&gt;call_user_func_array&lt;/strong&gt;, in a situation like this, we'd have to resort to a huge switch statement that counted the number of arguments and then invoked call_user_func with exactly the right count.&lt;/p&gt;
&lt;p&gt;There is another way to dynamically invoke callables, using reflection, which will be the subject of a short follow-up post.&lt;/p&gt;
&lt;h2&gt;Calling all Callables! (Directly)&lt;/h2&gt;
&lt;p&gt;Let's have a little fun and tie together concepts from each post in the series thus far to create a uniform means for doing direct dynamic invocation. To accomplish this we'll use &lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;PHP's closures and anonymous functions&lt;/a&gt; (part I) to create a &lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;higher-order PHP function&lt;/a&gt; (part II) that will return a directly invokable value for all callables&amp;nbsp; (part III). We're going to totally unify our dynamic invocations so we don't have to use call_user_func in our code, but can instead do this:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function aFunFunction() { echo "Radical."; }
$function = callable('aFunFunction');
$function();

$lambda = callable(function() { echo "Awesome!"; });
$lambda();

class Object { 
    function method() { echo "Great success!"; }
    static function staticMethod() { echo "More great success!"; }
}
$method = callable(array(new Object, 'method'));
$method();

$staticMethod = callable(array('Object','staticMethod'));
$staticMethod();
&lt;/pre&gt;
&lt;p&gt;Now we just need to write this callable method. If you think back to our wrapper example, it's got the hints we need. Our callable function will return an anonymous function that closes over the callable. Ready?&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function callable($aCallable) { 
     if(!is_callable($aCallable)) { 
		throw new Exception("Callable only works on is_callable's!");
	}
    // Return our anonymous function
    return function() use ($aCallable) {
        return call_user_func_array($aCallable, func_get_args());
    };
}&lt;/pre&gt;
&lt;p&gt;Pretty awesome, but I know what you're thinking. You're right, you can do better. Remember what we started out learning in this post? There are two kinds of callables that are directly callable: strings and anonymous functions. (Aside: there are actually three, the third is an object that implements the magical __invoke method, we'll get there later in this series.) Right, strings and anonymous functions can be called directly, it's the callables in the form of an array that need call_user_func. We can make our code a lot faster by simply returning callable non-arrays because they're already directly callable!&lt;/p&gt;
&lt;pre name="code" class="php"&gt;function callable($aCallable) {
	if(!is_callable($aCallable)) { 
		throw new Exception("Callable only works on is_callable's!");
	}
    if(!is_array($aCallalbe)) return $aCallable;
    return function() use ($aCallable) {
        return call_user_func_array($aCallable, func_get_args());
    };
}&lt;/pre&gt;
&lt;p&gt;Awesome. Just awesome. Using a closure we've brought unification to direct dynamic invocation in PHP 5.3 with our shiny new &lt;strong&gt;callable&lt;/strong&gt; function.&lt;/p&gt;
&lt;p&gt;Just a simple example of the power and flexibility functional PHP 5.3 brings to the table. Are you enjoying this series? Let me know in the comments. If so, &lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;you should subscribe to our RSS feed&lt;/a&gt; as parts IV and V are on their way...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - &lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;what is the difference between closures, lambdas, and anonymous functions?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2 - &lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;getting down and dirty with functional programming: callbacks, function types, and map reduce.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3 - &lt;a href="/page/php-callables-is-callable-call-user-func-array-reflection"&gt;dynamic invocation in PHP: is_callable, call_user_func, call_user_func_array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 4 - we'll exploit the pow[ers of XDebug to profile common uses of anonymous functions to understand their performance trade-offs.&lt;/li&gt;
&lt;li&gt;Part 5 - a first-hand look at how &lt;a href="/"&gt;Recess 5.3, a RESTful PHP framework&lt;/a&gt;, is using functional concepts to achieve simple flexibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also &lt;a href="http://www.twitter.com/KrisJordan"&gt;follow along on Twitter&lt;/a&gt; to get updates as this series continues...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/Nb8lmPMCn4Q" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/php-callables-is-callable-call-user-func-array-reflection</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/php-callables-is-callable-call-user-func-array-reflection</feedburner:origLink></item>
		<item>
		<title>Around the Recess PHP Community</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/8jfX3Ie04BE/around-the-recess-php-community</link>
		<description>&lt;p&gt;Just wanted to call out a couple of news items that have been bubbling up around the Recess developer community over the past week or so.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zdk put together a plugin for Smarty Views that is compatible with Recess 0.20. Download &lt;a href="http://recessframework.org/preview/content/files/recess-smarty-v0.20.zip"&gt;zdk's Recess Smarty Plugin here&lt;/a&gt; and check out the README for instructions in smarty/README.txt. He's also put together &lt;a href="http://recessframework.org/preview/content/files/recess-smarty-v0.20-example.zip"&gt;a simple Smarty / Recess demo app&lt;/a&gt;. Thanks zdk!&lt;/li&gt;
&lt;li&gt;Improvements to the database stack were brought into &lt;a href="http://github.com/recess/recess/commits/"&gt;Recess Edge on Github&lt;/a&gt; thanks to commits from &lt;a href="http://github.com/recess/recess/commit/4ca5ff9ce7cb3534fd7f021e6fbc3c1cf81f146e"&gt;KevBurnsJr's groupBy&lt;/a&gt; and midnightmonster's exists.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://kevburnsjr.com/"&gt;&lt;/a&gt;Preview scripts for the &lt;a href="http://wiki.recessframework.org/php/Recess_Sandbox"&gt;Recess Sandbox&lt;/a&gt;, a virtual Ubuntu development environment preconfigured with all the best open-source tools to do first class &lt;a href="http://github.com/recess/sandbox/"&gt;PHP software engineering are now available on Github&lt;/a&gt;. &lt;a href="http://wiki.recessframework.org/php/Recess_Sandbox#Prereqs"&gt;Setup instructions can be found on the Recess PHP Wiki&lt;/a&gt; (that just came online this past week and needs some help!). Expect some full-blown articles on Sandbox soon, but if you can't wait to get your hands dirty feel free to play. The Recess Sandbox setup comes loaded with:
&lt;ul&gt;
&lt;li&gt;Server Software
&lt;ul&gt;
&lt;li&gt;Apache 2.2&lt;/li&gt;
&lt;li&gt;PHP 5.3 w/ a Lot of Extensions&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PHP IDE
&lt;ul&gt;
&lt;li&gt;Eclipse PDT 2.1&lt;/li&gt;
&lt;li&gt;Integrated Debugging&lt;/li&gt;
&lt;li&gt;Syntax auto-completion with Recess&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interactive Debugging
&lt;ul&gt;
&lt;li&gt;XDebug Installed and Configured&lt;/li&gt;
&lt;li&gt;Ready to hook-up IDE and XDebug&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Profiling
&lt;ul&gt;
&lt;li&gt;Profile any script with an additional query string&lt;/li&gt;
&lt;li&gt;Visualize and inspect call graphs with KCacheGrind&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Unit Testing&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;PHPUnit 3.4 setup&lt;/li&gt;
&lt;li&gt;Run Test Coverage reports&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Work on Recess 5.3, a branch of Recess that leverages many of PHP 5.3's new capabilities for an even more enjoyable PHP development experience, has begun in earnest. More news on this will start trickling in as our series on Functional PHP continues. If you're interested in the new functional PHP features be sure to check out the first two installments: &lt;a href="http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures"&gt;anonymous functions, closures, and lambdas in PHP 5.3&lt;/a&gt; and &lt;a href="http://www.recessframework.org/page/map-reduce-anonymous-functions-lambdas-php"&gt;understanding and implementing map and reduce in PHP&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Exciting times in the land of Recess and PHP. &lt;em&gt;What will this week have in store?&lt;/em&gt; &lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;Stay tuned to via RSS.&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/8jfX3Ie04BE" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/around-the-recess-php-community</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/around-the-recess-php-community</feedburner:origLink></item>
		<item>
		<title>Understanding and Implementing the famous map and reduce functions - (Functional PHP 5.3 Part II)</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/k78Y_Uk4ngw/map-reduce-anonymous-functions-lambdas-php</link>
		<description>&lt;p&gt;To demonstrate some uses of PHP 5.3's fun new anonymous functions let's implement the famous functions: &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In Part I we deconstructed the differences between &lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;anonymous functions, lambdas, and closures in PHP&lt;/a&gt;. You may want to get comfy with those terms before continuing here. As a refresher, lambdas and anonymous functions are essentially the same idea: functions that are values just like integers and strings. Closures are what enable lambdas to refer to or &lt;code&gt;use&lt;/code&gt; variables defined outside of the lambda, even after those variables have fallen out of scope. Now, onto map reduce.&lt;/p&gt;
&lt;h2&gt;We should chat about &lt;a href="http://en.wikipedia.org/wiki/The_birds_and_the_bees"&gt;the butterflies, the birds, and the bees&lt;/a&gt;...&lt;/h2&gt;
&lt;p&gt;By now you've heard the &lt;a href="http://www.reddit.com/r/programming/"&gt;cool kids&lt;/a&gt; at &lt;a href="http://news.ycombinator.com"&gt;school&lt;/a&gt; raving about the euphoria of recursion and lambdas with higher order functions like &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt;. We'll get there, we will, but first we need to have a little talk about butterflies, birds, and bees.&lt;/p&gt;
&lt;p&gt;There's a moment in every little caterpillar's life when it becomes a butterfly. Metamorphosis is a transformative process. It's a &lt;em&gt;transformation function&lt;/em&gt;, caterpillar in, butterfly out. &lt;code&gt;(Caterpillar) -&amp;gt; (Butterfly)&lt;/code&gt; What is important to understand is not how metamorphosis works but that it is a function, a special kind of function that transforms a caterpillar into a butterfly.&lt;/p&gt;
&lt;p&gt;Can you think of other functions that transform an input into an output? Sure: &lt;code&gt;function square($x) { return x * x; }&lt;/code&gt; or &lt;code&gt;strtolower&lt;/code&gt; or &lt;code&gt;function filter($dirty) { /* clean up */ return $clean; }&lt;/code&gt;. There are a lot of transformer functions! Some, like &lt;code&gt;square&lt;/code&gt; may take an input and give you the same type of input back &lt;code&gt;int -&amp;gt; int&lt;/code&gt;. Others, like metamorphosis, will take one type of input and give you another &lt;code&gt;caterpillar -&amp;gt; butterfly&lt;/code&gt;. For our purposes let's classify all of these types of functions simply &lt;strong&gt;transformer functions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/files/transformer.jpg" alt="Transformer!" width="350" height="147" /&gt;&lt;/p&gt;
&lt;p&gt;Are there other types of functions too? You bet. This is the point where we talk about the birds and the bees. On second thought, I've never really understood how birds and bees combine to make anything, so lets stick to butterflies. When two butterflies are come together in a certain way they create a new butterfly (yes, I know this analogy also has holes, just play along). Let's refrain from thinking about the details of how they come together, and focus on the beauty of what is happening. Two butterflies combining to make one! &lt;code&gt;(Butterfly, Butterfly) -&amp;gt; (Butterfly)&lt;/code&gt;. It's another function, a &lt;strong&gt;combiner function&lt;/strong&gt;, that takes two like things and results in another like thing.&lt;/p&gt;
&lt;p&gt;&lt;img title="Combiner!" src="/files/combiner.jpg" alt="Combiner!" width="350" height="207" /&gt;&lt;/p&gt;
&lt;h2&gt;So, what does this have to do with map / reduce and functional programming in PHP?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; are higher-order functions. This means each has a parameter that is a function, but not just any function. Each takes a special type of function. &lt;strong&gt;&lt;code&gt;map&lt;/code&gt; uses a transformer function and &lt;code&gt;reduce&lt;/code&gt; uses a combiner function.&lt;/strong&gt; &lt;code&gt;map&lt;/code&gt; transforms a list of things, like say a bunch of caterpillars, into a list of another things, like butterflies. &lt;code&gt;reduce&lt;/code&gt; reduces a list of things like butterflies until there's only one left. Here's a visual of how map reduce works:&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/map-reduce-butterflies.JPG"&gt;&lt;img src="/files/map-reduce-butterflies-small.JPG" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;The Code! For crying out loud, show us The Code!&lt;/h2&gt;
&lt;p&gt;Ok, ok. You get it! &lt;code&gt;map&lt;/code&gt; transforms a list of things into a list of other things, &lt;code&gt;reduce&lt;/code&gt; combines a list of things into one thing. What does this look like in PHP?&lt;/p&gt;
&lt;p&gt;PHP has two built-in functions: &lt;code&gt;&lt;a href="http://us3.php.net/array_map"&gt;array_map&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="http://us3.php.net/array_reduce"&gt;array_reduce&lt;/a&gt;&lt;/code&gt;. (Unfortunately the two functions take the array and the callback parameters in different orders. &lt;em&gt;We won't make that mistake when we implement map/reduce will we?&lt;/em&gt;) A callback has a lot of different meanings in PHP which we'll cover in the next post &lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;in this series&lt;/a&gt;. For now take a callback to mean an "anonymous function".&lt;/p&gt;
&lt;p&gt;The canonical &lt;code&gt;map&lt;/code&gt;/&lt;code&gt;reduce&lt;/code&gt; example is word counting. So let's take on the challenge in PHP: given an array of strings we must count the occurrences of each word in all strings. Here is our input and desired output:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
$lines = array(
             'one two three four',
             'two three four',
             'three four',
             'four',
             );
// Desired Output, array of type word =&amp;gt; count
// array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 2, 'three' =&amp;gt; 3, 'four' =&amp;gt; 4, ) 
?&amp;gt;

&lt;/pre&gt;
&lt;p&gt;Let's break down the problem into what we know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inputs: (String of Words)&lt;/li&gt;
&lt;li&gt;Output: Array(Word =&amp;gt; Count)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We need to get from our input type to our output type. How can we use a transformer function to get us half-way there? And a reducer to bring us home? Think of the caterpillars and the butterflies.&lt;/p&gt;
&lt;p&gt;Our caterpillar is a plain old, space delimited, lowercase string. Our transformer function must take a single string and metamorphosize it into our butterfly, the output type: a single array where keys are words and values are counts. &lt;code&gt;(Line of Words) -&amp;gt; (Array: Word =&amp;gt; Count)&lt;/code&gt; Let's code this anonymous transformer function up (we'll cheat and use PHP's built-in &lt;a href="http://us2.php.net/manual/en/function.array-count-values.php"&gt;array_count_values&lt;/a&gt; to count the words):&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
// Transforms (Line of Words) -&amp;gt; (Array: Word =&amp;gt; Count)
$lineToWordCounts = 
    function($line) { 
        return array_count_values(explode(' ', $line));
    };
    
// Test on a single line:
var_export($lineToWordCounts('one two three four'));
// Output: array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 1, 'three' =&amp;gt; 1, 'four' =&amp;gt; 1, )

// Test with array_map:
$counts = array_map($lineToWordCounts, $lines);
var_export($counts);
// Output: array ( 0 =&amp;gt; array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 1, 'three' =&amp;gt; 1, 'four' =&amp;gt; 1, ), 
//                 1 =&amp;gt; array ( 'two' =&amp;gt; 1, 'three' =&amp;gt; 1, 'four' =&amp;gt; 1, ),
//                 2 =&amp;gt; array ( 'three' =&amp;gt; 1, 'four' =&amp;gt; 1, ),
//                 3 =&amp;gt; array ( 'four' =&amp;gt; 1, ), )
?&amp;gt;

&lt;/pre&gt;
&lt;p&gt;Sweet mother nature! The strings have transformed into beautiful butterflies! Now all we need to do is combine them down into a single array. If we can write a &lt;em&gt;combiner function&lt;/em&gt; that takes two word count arrays and combines them into one we can use &lt;code&gt;reduce&lt;/code&gt; to combine all of them into one for a total word count. Let's take a stab:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php 
// Combiner (Array:Word=&amp;gt;Count,Array:Word=&amp;gt;Count)-&amp;gt;(Array:Word=&amp;gt;Count)
$sumWordCounts =
    function($countsL, $countsR) {
        // Get all the words
        $words = array_merge(array_keys($countsL), array_keys($countsR));
        $out = array();
        // Put them in a new (Array: Word =&amp;gt; Count)
        foreach($words as $word) {
            // Sum their counts
            $out[$word] = isset($countsL[$word]) ? $countsL[$word] : 0;
            $out[$word] += isset($countsR[$word]) ? $countsR[$word] : 0;
        }
        return $out;
    };
$totals = array_reduce($counts, $sumWordCounts, array());
var_export($totals);
// Output: array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 2, 'three' =&amp;gt; 3, 'four' =&amp;gt; 4, ) 
?&amp;gt;

&lt;/pre&gt;
&lt;p&gt;Just like that we've implemented a multi-line word count using PHP's built-in array_map and array_reduce functions and our very own transformer and combiner lambdas. The map step transforms each line from a string into an array of word counts for that line. The reduce step combines those arrays of word counts into a single total count for all lines.&lt;/p&gt;
&lt;p&gt;Now that we understand map's use of a transform function, and reduce's use of combine function, let's implement map and reduce on our own.&lt;/p&gt;
&lt;h2&gt;So, you're ready to implement map/reduce in PHP?&lt;/h2&gt;
&lt;p&gt;Map's implementation is so simple, it barely needs an explanation. All we're doing is calling the transform function on every input element and storing each result in an array to be returned. Here it is:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
/**
 * $transformer lambda(caterpillar) -&amp;gt; butterfly
 * $in array of caterpillars
 */
function map($transformer, $in) {
    $out = array();
    foreach($in as $item) {
        $out[] = $transformer($item);
    }
    return $out;
}
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Not too bad, eh? Somewhere &lt;a href="http://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)"&gt;John Mccarthy&lt;/a&gt;'s just stooled himself, I know. Hang tight, John, we'll get to recursion! Reduce is a little trickier because of edge cases where arrays with no or only 1 element are provided. Don't get caught in those details, just focus on the snippet where we've got more than 1 element to reduce:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
/**
 * $combiner lambda(butterfly, butterfly) -&amp;gt; butterfly
 * $in array of butterflies
 */
function reduce($combiner, $in, $identity) {
    if(count($in) &amp;lt;= 1) {
        $out = $identity;
    } else if(count($in) &amp;gt; 1) {
        $out = array_shift($in);
        do {
            $next = array_shift($in);
            $out = $combiner($out, $next);
        } while(!empty($in));
    }
    return $out;
}
$totals = reduce($sumWordCounts, map($lineToWordCounts, $lines), array());
var_export($totals);
// Output: array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 2, 'three' =&amp;gt; 3, 'four' =&amp;gt; 4, ) 
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With reduce we begin by shifting the first butterfly off the list. We combine it with the next butterfly to make a super butterfly. We then combine the super butterfly with the next butterfly on the list, and so on until we have the ultimate single butterfly. This is a little trippy at first so refer back to the diagram for a visual explanation.&lt;/p&gt;
&lt;h2&gt;Map/Reduce, Take 2: Recursive Implementations, Please&lt;/h2&gt;
&lt;p&gt;Remember those crazy trips to lambdaland full of recursion all the cool kids on Reddit and HN are taking? Well, your time has come, too. Our initial implementations of &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; were done imperatively with loops. The functional folks believe loops are, well, &lt;strong&gt;garbage&lt;/strong&gt;. (Don't worry, they're not.) Why do you need loops when you have recursive functions? How would &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; look if we got rid of the loops?&lt;/p&gt;
&lt;p&gt;Before we get there, let's implement a few helper functions to make our recursive implementations beautiful. Here they are:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
// First element of an array
function first($in) { 
    return empty($in) ? null : $in[0];
}

// Everything after the first element of an array
function rest($in) {
    $out = $in;
    if(!empty($out)) { array_shift($out); }
    return $out;
}

// Take an element and an array
//  and fuse them together so that the element
//  is at the front of the array
function construct($first, $rest) {
    array_unshift($rest, $first);
    return $rest;
}
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now that we've got those helpers out of the way, allowing us to work with arrays like they're lists, let's do recursive &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; functions in PHP.&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
/**
 * $transformer lambda(caterpillar) -&amp;gt; butterfly
 * $in array of caterpillars
 */
function map($transformer, $in) {
    return !empty($in) ?    construct(  $transformer(first($in)), 
                                        map($transformer,rest($in)))
                        :    array();
};

/**
 * $combiner lambda(butterfly, butterfly) -&amp;gt; butterfly
 * $in array of butterflies
 */
function reduce($combiner, $in, $identity) {
    return !empty($in) ?    $combiner(first($in),
                                      reduce($combiner, rest($in), $identity))
                         :  $identity;
};

$totals = reduce($sumWordCounts, map($lineToWordCounts, $lines), array());
var_export($totals);
// Output: array ( 'one' =&amp;gt; 1, 'two' =&amp;gt; 2, 'three' =&amp;gt; 3, 'four' =&amp;gt; 4, ) 
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If you're more comfortable with for loops than recursion this is going to look trippy. Chew on it a little longer.&lt;/p&gt;
&lt;p&gt;Some things that may help you reason about the recursive version of map:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If there is at least one caterpillar, it will be transformed. map then calls itself with any remaining caterpillars.&lt;/li&gt;
&lt;li&gt;Once there are no caterpillars left, this is our base case: an empty array is returned.&lt;/li&gt;
&lt;li&gt;Once the empty array is returned, the previous map will construct a new array with its butterfly and return the array.&lt;/li&gt;
&lt;li&gt;The construction of the butterflies array happens one-by-one until every butterfly is in it, and the top-level map returns.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How did that feel for you? Beautifully functional? No loops, yet, we're iterating through a list!&lt;/p&gt;
&lt;p&gt;I'll leave the interpretation of reduce for you to mull over. We've now written higher-order functions by implementing map and reduce, imperatively and functionally, in PHP 5.3 with anonymous functions.&lt;/p&gt;
&lt;h2&gt;So, That Was Fun. What's Next?&lt;/h2&gt;
&lt;p&gt;We've deciphered lambdas, anonymous functions, and closures, now we've seen higher order functions with callbacks by implementing map/reduce, so what's next? Follow the RSS feed for the upcoming articles in this &lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;series on functional PHP 5.3&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - &lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;what is the difference between closures, lambdas, and anonymous functions?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2 - getting down and dirty with functional programming: &lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;callbacks, function types, and map reduce&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part 3 - &lt;a href="/page/php-callables-is-callable-call-user-func-array-reflection"&gt;dynamically invoke lambdas, functions, and methods with is_callable, call_user_func, and call_user_func_array&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part 4 - we'll exploit the powers of XDebug to profile common uses of anonymous functions to understand their performance trade-offs.&lt;/li&gt;
&lt;li&gt;Part 5 - a first-hand look at how Recess 5.3, a RESTful PHP framework, is using functional concepts to achieve simple flexibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You should &lt;a href="http://www.twitter.com/KrisJordan"&gt;follow me on Twitter&lt;/a&gt; to get updates as this series continues to evolve.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/k78Y_Uk4ngw" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/map-reduce-anonymous-functions-lambdas-php</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/map-reduce-anonymous-functions-lambdas-php</feedburner:origLink></item>
		<item>
		<title>Functional PHP 5.3 Part I - What are Anonymous Functions and Closures?</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/hfXMGiQFGdw/functional-php-anonymous-functions-lambdas-closures</link>
		<description>&lt;p&gt;One of the most exciting features of PHP 5.3 is the first-class support for &lt;a href="http://us.php.net/manual/en/functions.anonymous.php"&gt;anonymous functions&lt;/a&gt;. You may have heard them referred to as &lt;a href="http://us.php.net/manual/en/functions.anonymous.php"&gt;closures&lt;/a&gt; or lambdas as well. There's a lot of meaning behind these terms so let's straighten it all out.&lt;/p&gt;
&lt;h2&gt;What is the difference between Anonymous Functions, Lambdas, and Closures?&lt;/h2&gt;
&lt;p&gt;You'll see the terms "anonymous functions", "lambdas", and "closures" thrown around in reference to the new features of PHP 5.3. Even the the URL &lt;a href="http://www.php.net/closures/"&gt;php.net/closures&lt;/a&gt; redirects to &lt;a href="http://us3.php.net/manual/en/functions.anonymous.php"&gt;php.net/manual/functions.anonymous.php&lt;/a&gt;. The difference between 'lambda' and 'anonymous function'? None, for all intents and purposes they are two words for the same concept which is a descendant of &lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;lambda calculus&lt;/a&gt;. Languages with anonymous functions consider &lt;em&gt;functions&lt;/em&gt; to be first-class value types, just like integers or booleans. Anonymous functions can thus be passed as arguments to another function or even returned by a function. Let's make this concrete in PHP:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
$lambda = function() { 
            echo "I am an anonymous function, 
                  aka a lambda!&amp;lt;br /&amp;gt;";
            };
$anonymousFunction = $lambda;
$anonymousFunction(); 
// Output: I am an anonymous function, aka a lambda!

function nCallsTo($n, $function) {
    for($i = 0; $i &amp;lt; $n; $i++) {
        $function();
    }
    return function() { echo "I am also an anonymous function!&amp;lt;br /&amp;gt;"; };
}

$anotherAnon = nCallsTo(3, $anonymousFunction);
// Output:
// I am an anonymous function, aka a lambda!
// I am an anonymous function, aka a lambda!
// I am an anonymous function, aka a lambda!

$anotherAnon();
// Output: I am also an anonymous function!
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice how we did not assign a name to the function, we assigned a function to be the value of a variable. Just like a string or any other primative. We then assign it to another variable. The function is just a value, it has no name, hence the term "anonymous function". We then create a regular function named &lt;code&gt;nCallsTo&lt;/code&gt; that takes two arguments, &lt;code&gt;$n&lt;/code&gt; being the number of times to make a call to &lt;code&gt;$function&lt;/code&gt; an anonymous function.&lt;/p&gt;
&lt;p&gt;The existance of higher-order functions opens the door for techniques like &lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;map/reduce&lt;/a&gt;&lt;a&gt;&lt;/a&gt;&lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;next post&lt;/a&gt;.&lt;code&gt;nCallsTo&lt;/code&gt; is a higher-order function on two accounts: 1) it takes a function as an argument, and 2) it returns a function as a value. Higher-order functions open the doors for techniques like &lt;a href="http://us3.php.net/array_map"&gt;map&lt;/a&gt;/&lt;a href="http://us3.php.net/manual/en/function.array-reduce.php"&gt;reduce&lt;/a&gt; and deserves a post in itself. The point is &lt;strong&gt;lambdas and anonymous functions are the same things: functions that are values&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If anonymous functions are values, what does PHP consider their type to be? Let's find out:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php 
$lambda = function() { echo "anonymous function"; };
echo gettype($lambda) . '&amp;lt;br /&amp;gt;';
// Output: object
echo get_class($lambda) . '&amp;lt;br /&amp;gt;';
// Output: Closure
?&amp;gt;

&lt;/pre&gt;
&lt;h2&gt;On the Closure object in PHP 5.3&lt;/h2&gt;
&lt;p&gt;What is a closure? So far it's a misnomer. We haven't actually spotted a closure even though PHP assigns all anonymous functions the type &lt;code&gt;Closure&lt;/code&gt;. Since we haven't actually seen a closure yet, let's take a look at one:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php
function letMeSeeAClosure() {
    $aLocalNum = 10;
    return function() use (&amp;amp;$aLocalNum) { return ++$aLocalNum; };
}
$aClosure = letMeSeeAClosure();
echo $aClosure();
// Output: 11
echo $aClosure();
// Output: 12
$anotherClosure = letMeSeeAClosure();
echo $anotherClosure();
// Output: 11
echo $aClosure();
// Output: 13
echo $aLocalNum;
// Notice: Undefined Variable: aLocalNum&lt;br /&gt;?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Chew on that for a minute. Do you spot the funny business? &lt;code&gt;$aLocalNum&lt;/code&gt; is a local variable defined within the scope of the plain-old function &lt;code&gt;letMeSeeAClosure&lt;/code&gt;. With the new &lt;code&gt;use&lt;/code&gt; syntax the variable &lt;code&gt;$aLocalNum&lt;/code&gt; is bound or &lt;strong&gt;closed over&lt;/strong&gt; to create the closure. This allows the returned Closure to retain a reference to &lt;code&gt;$aLocalNum&lt;/code&gt;, even after &lt;code&gt;$aLocalNum&lt;/code&gt; falls out of lexical scope when the function returns. The notice error occurs when trying to reference &lt;code&gt;$aLocalNum&lt;/code&gt; directly from outside of the function's scope.&lt;/p&gt;
&lt;p&gt;To recap, the terms, 'lambda' or 'anonymous function' refer to the same concept: functions that are values. Closures refer to a related, but different concept: the lifetime of a variable that is 'closed over', or in PHP 5.3 &lt;code&gt;use&lt;/code&gt;'d, by a closure, is bound to the lifetime, or &lt;a href="http://en.wikipedia.org/wiki/Variable_(programming)#Scope_and_extent"&gt;extent&lt;/a&gt;, of the closure. &lt;strong&gt;&lt;em&gt;Anonymous functions&lt;/em&gt; that are constructed with the &lt;code&gt;use&lt;/code&gt; keyword are also &lt;em&gt;closures&lt;/em&gt;.&lt;/strong&gt; As mentioned, in PHP 5.3, anonymous functions are typed as &lt;code&gt;Closure&lt;/code&gt; and the three words have, so far, been thrown about. The high-order bit to take away is an understanding that PHP 5.3 now includes language features for anonymous functions and closures.&lt;/p&gt;
&lt;h3&gt;More on Functional PHP 5.3&lt;/h3&gt;
&lt;p&gt;If you're interested in PHP software development you should &lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;subscribe to our feed&lt;/a&gt;. Upcoming parts to this series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/page/functional-php-anonymous-functions-lambdas-closures"&gt;Part 1 - the differences between closures, lambdas, and anonymous functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="/page/map-reduce-anonymous-functions-lambdas-php"&gt;Part 2 - getting down and dirty with functional programming: callbacks, function types, and map reduce&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="/page/php-callables-is-callable-call-user-func-array-reflection"&gt;Part 3 - dynamically invoke lambdas, functions, and methods with is_callable, call_user_func, and call_user_func_array&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Part 4 - we'll exploit the powers of XDebug to profile common uses of anonymous functions to understand their performance trade-offs.&lt;/li&gt;
&lt;li&gt;Part 5 - a first-hand look at how Recess 5.3, a RESTful PHP framework, is using functional concepts to achieve simple flexibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://feeds2.feedburner.com/RecessFramework"&gt;Follow this series on RSS&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/hfXMGiQFGdw" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures</feedburner:origLink></item>
		<item>
		<title>Screencast: Recess with Multiple Sites</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/eYgFO0ATk2k/screencast-recess-with-multiple-sites</link>
		<description>&lt;p&gt;&lt;a href="http://kevburnsjr.com/"&gt;Kevin Burns&lt;/a&gt; put together a great screencast demonstrating how to work with multiple sites using one copy of Recess. &lt;a href="http://www.screencast.com/users/KevBurnsJr/folders/Jing/media/47ea12d0-8ed8-4eb3-999d-67b935657991"&gt;Check it...&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.screencast.com/users/KevBurnsJr/folders/Jing/media/47ea12d0-8ed8-4eb3-999d-67b935657991"&gt;&lt;img title="Screencast: Multiple Sites with Recess" src="http://www.recessframework.org/files/images/screencast-recess-with-multiple-sites/screencast.png" alt="Screencast: Multiple Sites with Recess" width="450" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kevin Burns is a web developer from Menlo Park, CA. He has been doing web design and development for 6 years and is available for work in the SF Bay Area. &lt;a href="http://kevburnsjr.com/" target="_blank"&gt;http://kevburnsjr.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/eYgFO0ATk2k" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/screencast-recess-with-multiple-sites</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/screencast-recess-with-multiple-sites</feedburner:origLink></item>
		<item>
		<title>Recess .2 Release</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/oeBiw4IHxU0/recess-oh-two-release</link>
		<description>&lt;p&gt;It's been a long journey since the release of .12 in April. With the exciting release of PHP 5.3 we wanted to push out bulk of the planned .2 changes as soon as possible, which include some fixes to not break a couple of PHP features deprecated in 5.3. Other features that are in this release:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.recessframework.org/book/html/ch06.html"&gt;Refined, More Extensible Core Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.recessframework.org/book/html/ch06s06.html"&gt;Custom Annotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Simpler Directory Structure&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.recessframework.org/book/html/ch10.html"&gt;New Views, Layouts, Parts, and Blocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.recessframework.org/page/recess-php-content-negotiation"&gt;Content-Negotiation and Format based View Selection&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Runs in PHP 5.3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Get the bits in &lt;a href="http://www.recessframework.org/preview/content/files/recess-v0.20.zip"&gt;zip&lt;/a&gt; or &lt;a href="http://www.recessframework.org/preview/content/files/recess-v0.20.tar.gz"&gt;tarball&lt;/a&gt; form while they're hot!&lt;/p&gt;
&lt;p&gt;We learned a big lesson in the 4 month development process moving Recess from 0.12 to 0.20: we were ambitious and took a big bite, perhaps a bit more than we could chew. The new controls/validation model still isn't ready for this release. (If you're adventurous you can find some prototyping in 0.20's bits!) Lesson learned: moving forward development be focused on fewwer features at a time and released as they are completed.&lt;/p&gt;
&lt;p&gt;With the release of 5.3 now nearly a month past it is clear that namespaces, late static binding, lambdas, and the dramatic performance improvements are going to make 5.3 the PHP version of choice for new PHP projects. Our next focus is on a 5.3 Recess branch that leverages these powerful, fundamental language features to make developing in PHP more enjoyable.&lt;/p&gt;
&lt;p&gt;Next week there will be more discussion on what to expect with Recess 5.3, the launch of a Recess wiki (finally!), and some tutorials on new features in PHP 5.3.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/oeBiw4IHxU0" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/recess-oh-two-release</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/recess-oh-two-release</feedburner:origLink></item>
		<item>
		<title>Introducing the 0.20 Layouts System - Part I</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/ZeJaSAJdMvg/new-layouts-blocks-assertive-templates-system</link>
		<description>&lt;p&gt;One of the biggest features going into Recess 0.20 is the new layouts system for views and display logic largely inspired by Joshua Paine's original work. It has been in the making since February and, with &lt;a href="http://github.com/recess/recess/commit/ab789774113a0122510810f6e3274c7073899fb2"&gt;the latest changeset on GitHub&lt;/a&gt;, &lt;strong&gt;the view system is finally there after going through 3 major iterations&lt;/strong&gt;. For those who have been following along and familiarized yourselves with the existing slots/blocks system I want to take some time to explain how the final system works. It is a simplification of the slots/blocks scheme with some additional new functionality.&lt;/p&gt;
&lt;p&gt;In Recess 0.20 and beyond view code will revolve around 2 fundamental concepts: &lt;strong&gt;blocks&lt;/strong&gt; and &lt;strong&gt;assertive templates&lt;/strong&gt; which drive layouts and parts.&lt;/p&gt;
&lt;h2&gt;Buffering to Blocks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Blocks are objects that contain unrendered output.&lt;/strong&gt; Think of a Block as a hunk of HTML you can pass around and manipulate before rendering. &lt;code&gt;Block&lt;/code&gt; is an abstract class with multiple sub-class implementations. You can create a simple block by instantiating &lt;code&gt;HtmlBlock&lt;/code&gt;:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?
$block = new HtmlBlock(
    "&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;" .
	"&amp;lt;p&amp;gt;Welcome to Recess 0.20&amp;lt;/p&amp;gt;"
);
echo $block;
?&amp;gt;&lt;/pre&gt;
&lt;p&gt;The result of this code would be the contents sent to output. If you saw the previous iteration of blocks and slots you may be thinking, &lt;em&gt;"Why write HTML in strings? Isn't the point of Blocks &lt;strong&gt;not&lt;/strong&gt; to do that?"&lt;/em&gt; One of the realizations in the last view iteration was that Blocks were confounding two orthogonal concerns: 1) conveniently buffering output and 2) holding onto the output for later use. We broke out these two responsibilities so now &lt;strong&gt;Blocks are concerned with retaining output&lt;/strong&gt; and &lt;strong&gt;the Buffer helper is concerned with buffering output&lt;/strong&gt; to a block. The &lt;strong&gt;Buffer fills Blocks.&lt;/strong&gt; Let's take a look:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;? Buffer::to($block) ?&amp;gt;
   &amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;
   &amp;lt;p&amp;gt;Welcome to Recess 0.20&amp;lt;/p&amp;gt;
&amp;lt;? Buffer::end ?&amp;gt;
&amp;lt;?= $block ?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With more content being buffered and/or complex display logic the benefits of buffering output to blocks becomes much more convenient. You can append to, prepend to, and overwrite the content of the resulting blocks with methods on the block instance or using the Buffer helpers.&lt;/p&gt;
&lt;h2&gt;Layout, an Assertive Template&lt;/h2&gt;
&lt;p&gt;Most web applications share HTML between many different views. PHP has a simple way of including common HTML between scripts: the &lt;a href="http://us3.php.net/include()"&gt;include statement&lt;/a&gt;. It is not uncommon to see include('header.php'), include('footer.php'), etc. The downside to using this method of including scripts is that it introduces structural dependencies throughout all of your view code. Recess' inverts this dependency problem with layouts. A view script can extend a single layout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is a layout? A layout is a template with defined inputs. A layout uses the inputs, provided by a child template extending the layout, to fill in slots of HTML.&lt;/strong&gt; Let's take a look at a simple example (simple.layout.php):&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?php/*Input Variable   Type      Default Value
--------------------------------------------------------*/
Layout::input($title,   'string', 'The Resilient Layout');
Layout::input($sidebar, 'Block');
Layout::input($body,    'Block');
?&amp;gt;
&amp;lt;html&amp;gt;
	&amp;lt;head&amp;gt;
		&amp;lt;title&amp;gt;&amp;lt;?= $title ?&amp;gt;&amp;lt;/title&amp;gt;
	&amp;lt;/head&amp;gt;
	&amp;lt;body&amp;gt;
		&amp;lt;div id="container"&amp;gt;
			&amp;lt;div id="sidebar"&amp;gt;
			&amp;lt;? if(!$sidebar-&amp;gt;draw()): ?&amp;gt;
				&amp;lt;ul&amp;gt;
				  &amp;lt;li&amp;gt;Default Link A&amp;lt;/li&amp;gt;
				  &amp;lt;li&amp;gt;Default Link B&amp;lt;/li&amp;gt;
				  &amp;lt;li&amp;gt;Default Link C&amp;lt;/li&amp;gt;
				&amp;lt;/ul&amp;gt;
			&amp;lt;? endif ?&amp;gt;
			&amp;lt;/div&amp;gt;
			&amp;lt;div id="content"&amp;gt;
			&amp;lt;? if(!$body-&amp;gt;draw()): ?&amp;gt;
				&amp;lt;p&amp;gt;Default content.&amp;lt;/p&amp;gt;
			&amp;lt;? endif ?&amp;gt;
			&amp;lt;/div&amp;gt;
		&amp;lt;/div&amp;gt;
	&amp;lt;/body&amp;gt;
&amp;lt;? 
if(isset($die)) {
	die('By accident or affliction, a child template cannot kill me'
		. ', for I will never take $die as an input.');
}
?&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice Blocks have a &lt;code&gt;draw&lt;/code&gt; method. If the &lt;code&gt;Block&lt;/code&gt; contains output it will be printed and return true, else it will return false. For Recess Edge followers, the &lt;code&gt;if(!$block-&amp;gt;draw){} construct&lt;/code&gt; is equivalent to the previous &lt;code&gt;Layout::slot('block'); Layout::slotEnd();&lt;/code&gt; mechanism.&lt;/p&gt;
&lt;p&gt;Also notice in the layout we define our input variables, their respective types, and any default values. This makes the layout an &lt;strong&gt;Assertive Template&lt;/strong&gt;. &lt;strong&gt;Assertive templates declare their inputs.&lt;/strong&gt; You may be wondering, why does the parent layout not simply inherit the entire context of the child? What justifies the extra typing?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Design by Contract&lt;/strong&gt; - Layouts define an input contract. If your child template does not fulfill the contract Recess will immediately fail and tell you the error is in the child template not providing an input. Compare this to the obscure '$foo is not defined in parent.php at line 305' error message you would otherwise receive: Is the bug in the child script or the parent layout? You would have to understand the logic of both to pinpoint the problem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fewer Surprises&lt;/strong&gt; - The only variables that exist in a parent layout are those declared as inputs. If the input requirements aren't met the child template is to blame, if the input requirements are met, then the parent layout is to blame. To reason about the behavior of an assertive template you only need to reason about one script at a time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self Documenting&lt;/strong&gt; - What variables does a layout expect? With assertive templates this is easy: just look at the inputs. Without assertive templates this can be a pain: you must completely understand all of the code in another script.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can extend the simple layout in a view template with the following code:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;&amp;lt;?
Layout::extend('simple')
$title = 'A Simple Layout'
$die = true; // Has no effect.
?&amp;gt;

&amp;lt;? Buffer::to($sidebar): ?&amp;gt;
&amp;lt;ul&amp;gt;
 &amp;lt;li class="selected"&amp;gt;
  &amp;lt;?=html::anchor(url::action('Controller::method'),'Link 1')?&amp;gt;
 &amp;lt;/li&amp;gt;
 &amp;lt;li&amp;gt;
  &amp;lt;?=html::anchor(url::action('Controller::method2'),'Link 2')?&amp;gt;
 &amp;amp;;/li&amp;gt;
 &amp;lt;li&amp;gt;
   &amp;lt;?=html::anchor(url::action('Controller::method3'),'Link 3')?&amp;gt;
 &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;? Buffer::end() ?&amp;gt;

&amp;lt;h1&amp;gt;Body&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;$body is a special Block that is created implicitly 
   if not defined explicitly.&amp;lt;/p&amp;gt;
&amp;nbsp;
&lt;/pre&gt;
&lt;p&gt;By using the &lt;code&gt;Layout&lt;/code&gt; helper's &lt;code&gt;extend&lt;/code&gt; method we declare that we're inheriting from simple.layout.php. Once the child template has executed the variables declared as inputs to the parent layout will be extracted from the child template and passed to the parent. There are two Block inputs in the layout: &lt;code&gt;$sidebar&lt;/code&gt; and &lt;code&gt;$body&lt;/code&gt;. The child template uses the Buffer technique described above to fill the &lt;code&gt;$sidebar&lt;/code&gt; block. &lt;strong&gt;The &lt;code&gt;$body&lt;/code&gt; block is filled by a special case: any output in a child template will automatically fill a block named &lt;code&gt;$body&lt;/code&gt;&lt;/strong&gt;, unless the child template defines &lt;code&gt;$body&lt;/code&gt; explicitly.&lt;/p&gt;
&lt;p&gt;Notice that we assign true to variable &lt;code&gt;$die&lt;/code&gt; in the child, and in the parent there is a conditional that will kill the script if &lt;code&gt;$die&lt;/code&gt; is set. The parent layout will not die, though, because &lt;code&gt;$die&lt;/code&gt; is not an input of the layout. &lt;strong&gt;Layouts only acquire the scope their inputs they define!&lt;/strong&gt; This is, admittedly, a contrived example.&lt;/p&gt;
&lt;p&gt;In Part II of this look at Recess 0.20's new view system we will cover &lt;strong&gt;Parts&lt;/strong&gt;, Recess' spin on partial templates, and the powerful &amp;amp; mystical &lt;code&gt;Block&lt;/code&gt; that is a &lt;code&gt;Part&lt;/code&gt;: &lt;code&gt;PartBlock&lt;/code&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/ZeJaSAJdMvg" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/new-layouts-blocks-assertive-templates-system</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/new-layouts-blocks-assertive-templates-system</feedburner:origLink></item>
		<item>
		<title>New Features on Recess Edge</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/inpR02krRlk/recess-php-content-negotiation</link>
		<description>&lt;p&gt;We're approaching the 0.2 release quickly. It represents the biggest leap in functionality for the framework yet. We've just pushed two major, related features to &lt;a href="http://www.github.com/recess/recess/"&gt;Recess Edge on Github&lt;/a&gt;: a new view selection process and content-negotiation. For folks who like to try development bits, when checking out Edge, here are some pointers on what to expect with the most recent commits:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: arial; font-size: 13px; border-collapse: collapse;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;New View Selection System based on Requested Format&lt;/h2&gt;
&lt;p&gt;The new native view system looks for an application's view template by matching a format to a file-extension. So, for example, if a visitor requests '/foo.xml' and your controller returns a view-name of 'foo', Recess now looks for the view template foo.xml.php - the same goes with json, rss, pdf, etc. For the default html format there is no additional extension, it's still just foo.php.&lt;/p&gt;
&lt;p&gt;What about automatic JSON? It is no longer turned on by default (though, if you are using existing code, it should still work in version 0.20 but is now considered deprecated and will not be supported in 0.30). Recess has a new, more advanced mechanism for selecting views. Multiple views can be registered with a controller with the new !RespondsWith annotation, it looks like this:&lt;/p&gt;
&lt;pre&gt;/**
  * !RespondsWith Layouts, Json
  * !Prefix my/
  */
class MyController extends Controller {
  &amp;nbsp;function foo() { }
}&lt;/pre&gt;
&lt;p&gt;The !Prefix annotation will be discussed shortly. Layouts and Json are both views with class names LayoutsView, JsonView respectively. These form the prioritized list which Recess will use to find a view. Suppose 'my/foo.json' is requested by the client. In this case LayoutsView will be asked first 'can you render this response?', if the view template 'my/foo.json.php' exists then answer is yes and it will render and we're done. If that file does not exist, though, then the new JsonView will be asked 'can you render this response?' and it can always render &amp;nbsp;a json request so it will. If you *always* wanted to use automatic-json for json requests then you could simply reverse the order: Json, Native. This avoids the cost of checking the file system for a json template file.&lt;/p&gt;
&lt;p&gt;A list of the supported formats is provided in the following section.&lt;/p&gt;
&lt;h2&gt;More RESTful Goodness with Accept-based PHP Content-Negotiation&lt;/h2&gt;
&lt;p&gt;Recess now has support for parsing the HTTP Accept header (&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" target="_blank"&gt;&lt;span style="color: #000000;"&gt;&lt;span style="text-decoration: none;"&gt;http://www.w3.org/Protocols/&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;span style="text-decoration: none;"&gt;rfc2616/rfc2616-sec14.html&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;) for content-negotiation! This means for folks using RIAs and smart-clients you can interact with your Recess applications truer to the way HTTP intends. Instead of appending a format like '.json' to a URL your clients can now use 'Accept: application/json'. Here are a list of supported mime-types and the formats they map to:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;html = text/html, application/xhtml+xml&lt;/pre&gt;
&lt;pre&gt;xml = application/xml, text/xml, application/x-xml&lt;/pre&gt;
&lt;pre&gt;json = application/json, text/x-json application/jsonrequest&lt;/pre&gt;
&lt;pre&gt;js = text/javascript, application/javascript, application/x-javascript&lt;/pre&gt;
&lt;pre&gt;css = text/css&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;rss = application/rss+xml&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;yaml = application/x-yaml, text/yaml&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;atom = application/atom+xml&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;pdf = application/pdf&lt;/pre&gt;
&lt;pre&gt;text = text/plain&lt;/pre&gt;
&lt;pre&gt;png = image/png&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;jpg = image/jpeg, image/pjpeg&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;gif = image/gif&lt;/pre&gt;
&lt;pre&gt;form = multipart/form-data&lt;/pre&gt;
&lt;pre&gt;url-form = application/x-www-form-urlencoded&lt;/pre&gt;
&lt;pre&gt;csv = text/csv&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the rare case you need to accept a MIME-types not listed above you can add it to the mix with the following: MimeTypes::register('foo', 'application/foo'); The second argument can also be an array to support multiple mime types referring to the same format.&lt;/p&gt;
&lt;h2&gt;New Controller Annotation: !Prefix&lt;/h2&gt;
&lt;p&gt;It has become a common case in Recess development for the view and route prefix to be the same. A new annotation allows you to specify both with a single annotation:&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;!Prefix foo/ &amp;nbsp; &amp;nbsp; (now relative routes and views are prefixed with foo/)&lt;/pre&gt;
&lt;/div&gt;
&lt;pre&gt;!Prefix&amp;nbsp;Routes: /,&amp;nbsp;Views: home/ &amp;nbsp; &amp;nbsp; &amp;nbsp;(allows you to set them individually)&lt;/pre&gt;
&lt;h3&gt;Note: Deprecated Controller Annotations: !View, !RoutesPrefix&lt;/h3&gt;
&lt;p&gt;The !View annotation is still supported in 0.2 but is deprecated and will be unsupported in v0.3 - It is replaced by !RespondsWith&lt;/p&gt;
&lt;p&gt;The !RoutesPrefix annotation is still supported in 0.2 but is deprecated and replaced by !Prefix&lt;/p&gt;
&lt;h3&gt;Warning: Not-yet-backwards-compatible: PUTing / POSTing JSON&lt;/h3&gt;
&lt;p&gt;Work is still being done on data that is PUT/POSTed to the server with alternate MIME-types. For folks who depend on POSTing/PUTing JSON please hold off on pulling the latest bits from Edge. This is coming soon and will allow other content-type parsers (XML, for example) to be plugged-in. We're also decoupling the format of input from output, so, for example, you could post JSON and ask for HTML back.&lt;/p&gt;
&lt;div&gt;&lt;strong&gt;&lt;em&gt;We're getting really close to the 0.2 release and we need your help&lt;/em&gt;&lt;/strong&gt; in testing the bits, reporting and submitting patches for bugs, and contributing to the documentation. Can't wait to get 0.2 out the door!&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/inpR02krRlk" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/recess-php-content-negotiation</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/recess-php-content-negotiation</feedburner:origLink></item>
		<item>
		<title>How-to Help Document the Recess Framework</title>
		<link>http://feedproxy.google.com/~r/RecessFramework/~3/oeSHCkY7MYc/how-to-help-document-the-recess-framework</link>
		<description>&lt;p&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; color: #000000; font-family: arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;
&lt;div&gt;Documentation has been one of the sorest spots for new users of Recess. Until now it hasn't been possible for the community to contribute to documentation.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-size: large;"&gt;Recess could really use your help with documentation.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Over the last couple of days a big push was made to pull together the existing documentation into the DocBook XML format [&lt;a style="color: #0000cc;" href="http://www.docbook.org/" target="_blank"&gt;http://www.docbook.org/&lt;/a&gt;]. DocBook is a common format for technical books and documentation. It is plain-old-XML, is easily modified and contributed to, and has great support for generating down to XHTML, PDF and other formats.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Examples of published output with existing content can be found here:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;XHTML:&amp;nbsp;&lt;a style="color: #0000cc;" href="http://www.recessframework.org/book/html/index.html" target="_blank"&gt;http://www.recessframework.org/book/html/index.html&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;All-in-One XHTML:&amp;nbsp;&lt;a style="color: #0000cc;" href="http://www.recessframework.org/book/html/the-book-of-recess.html" target="_blank"&gt;http://www.recessframework.org/book/html/the-book-of-recess.html&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;PDF:&amp;nbsp;&lt;a style="color: #0000cc;" href="http://www.recessframework.org/book/pdf/the-book-of-recess.pdf" target="_blank"&gt;http://www.recessframework.org/book/pdf/the-book-of-recess.pdf&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-style: italic;"&gt;How to Contribute to Recess Documentation&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Using GitHub and XML documents we can now iterate on the Recess documentation together.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-weight: bold;"&gt;The docbook source can be found on github here:&amp;nbsp;&lt;a style="color: #0000cc;" href="http://github.com/recess/the-book-of-recess" target="_blank"&gt;http://github.com/recess/the-book-of-recess&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;First,&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;fork the repository on GitHub.&lt;/span&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;A forking guide for GitHub can be found here:&amp;nbsp;&lt;a style="color: #0000cc;" href="http://github.com/guides/fork-a-project-and-submit-your-modifications" target="_blank"&gt;http://github.com/guides/fork-a-project-and-submit-your-modifications&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Second,&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;run the ./scripts/install.sh script&lt;/span&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;from the base directory of the repository. This downloads/unpacks the Java libraries for processing DocBook to generate HTML and PDF with syntax highlighting.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- *nix folks this should just work&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- Windows folks use MinGW [&lt;a style="color: #0000cc;" href="http://code.google.com/p/msysgit/" target="_blank"&gt;http://code.google.com/p/msysgit/&lt;/a&gt;] and make sure you have the 'unzip' command available at the command line. If you do not, download the 'unzip' executables from here [&lt;a style="color: #0000cc;" href="http://sourceforge.net/project/showfiles.php?group_id=204414" target="_blank"&gt;http://sourceforge.net/project/showfiles.php?group_id=204414&lt;/a&gt;] and drop the executables in your mingw bin folder.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Third,&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;run the ./scripts/publish.sh&lt;/span&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;script from the base directory of the repository. The result should be a folder called 'pub' that has the HTML and PDF output.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Finally,&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;edit the book's content&lt;/span&gt;. Don't feel constrained to the structure that's currently in-place. Use the existing chapters for examples of how to mark-up code examples, sections of a chapter, etc. This page is also a great resource on Docbook's tags: [&lt;a style="color: #0000cc;" href="http://www.docbook.org/tdg5/en/html/docbook.html" target="_blank"&gt;http://www.docbook.org/tdg5/en/html/docbook.html]&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Anywhere you can contribute, add comments on, provide a source code example for, please do!&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;While the amount of documentation exists is sparse we should err on the side of quantity over quality. With editing we can refine the rough bits and iterate together towards having the best documentation of any PHP framework.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Finally, request a pull and your contributions will be merged into the documentation.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;If you have any questions or run into problems with the install/publish scripts leave comments below.&lt;br /&gt;&lt;/div&gt;
&lt;/span&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RecessFramework/~4/oeSHCkY7MYc" height="1" width="1"/&gt;</description>
		<guid isPermaLink="false">http://www.recessframework.org/page/how-to-help-document-the-recess-framework</guid>
		<pubDate>Mon, 09 Nov 2009 09:08:53 EST</pubDate>
	<feedburner:origLink>http://www.recessframework.org/page/how-to-help-document-the-recess-framework</feedburner:origLink></item>
		
</channel>
</rss>
