<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Federico Cargnelutti</title>
	<atom:link href="http://blog.fedecarg.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.fedecarg.com</link>
	<description>Simple is better than complex. Complex is better than complicated. &#124; @fedecarg</description>
	<lastBuildDate>Fri, 17 May 2013 02:02:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.fedecarg.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Federico Cargnelutti</title>
		<link>http://blog.fedecarg.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.fedecarg.com/osd.xml" title="Federico Cargnelutti" />
	<atom:link rel='hub' href='http://blog.fedecarg.com/?pushpress=hub'/>
		<item>
		<title>Intercepting class method invocations using metaclass programming in Python</title>
		<link>http://blog.fedecarg.com/2012/01/22/intercepting-class-method-invocations-using-metaclass-programming-in-python/</link>
		<comments>http://blog.fedecarg.com/2012/01/22/intercepting-class-method-invocations-using-metaclass-programming-in-python/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 19:52:14 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2190</guid>
		<description><![CDATA[In Ruby, objects have a handy method called method_missing which allows one to handle method calls for methods that have not been defined. Most examples out there explain how to implement this in Python using __getattr__, however, none of them (honestly, none) explain how to intercept class method (@classmethod) invocations using __metaclass__. And that&#8217;s why [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2190&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In Ruby, objects have a handy method called method_missing which allows one to handle method calls for methods that have not been defined. Most examples out there explain how to implement this in Python using __getattr__, however, none of them (honestly, none) explain how to intercept class method (@classmethod) invocations using __metaclass__.</p>
<p>And that&#8217;s why I wrote this post.</p>
<p>The function type is the built-in metaclass Python uses, it not only lets you know the type of an object, but also create classes on the fly. When you write, for example: class Example(object) the class object Example is not created in memory straight away. Python looks for the __metaclass__ attribute in the class definition and if it finds it, it uses it to create the object class Example. If it doesn&#8217;t, it uses type to create the class. The main purpose of a metaclass is to change the class automatically, when it&#8217;s created.</p>
<p>Here&#8217;s an example of how to use metaclass programming to intercept class method calls similar to the method_missing technique in Ruby:</p>
<pre>class ClassMethodInterceptor(type):

    def __getattr__(cls, name):
        return lambda *args, **kwargs: \
                   cls.static_method_missing(name, *args, **kwargs)

    def static_method_missing(cls, method_name, *args, **kwargs):
        e = "type object 'static.%s' has no attribute '%s'" \
            % (cls.__name__, method_name)
        raise AttributeError(e)

class Example(object):

    __metaclass__ = ClassMethodInterceptor

    def __getattr__(self, name):
        return lambda *args, **kwargs: \
                   self.method_missing(name, *args, **kwargs)

    def method_missing(self, method_name, *args, **kwargs):
        e = "type object '%s' has no attribute '%s'" \
            % (self.__class__.__name__, method_name)
        raise AttributeError(e)

    @classmethod
    def static(cls):
        print 'static.%s' % cls.__name__

    def instance(self):
        print self.__class__.__name__</pre>
<p>Console:</p>
<pre>&gt;&gt;&gt; Example.static()
static.Example
&gt;&gt;&gt; Example.foo()
Traceback (most recent call last):
...
  File "example.py", line 12, in static_method_missing
    raise AttributeError(e)
AttributeError: type object 'static.Example' has no attribute 'foo'
&gt;&gt;&gt; e = Example()
&gt;&gt;&gt; e.instance()
Example
&gt;&gt;&gt; e.foo()
Traceback (most recent call last):
...
  File "example.py", line 26, in method_missing
    raise AttributeError(e)

AttributeError: type object 'Example' has no attribute 'foo'</pre>
<p>If you ever implement something like this, remember that Python doesn&#8217;t distinguish between methods and attributes the way Ruby does. There is no difference in Python between properties and methods. A method is just a property whose type is instancemethod.</p>
<br />Filed under: <a href='http://blog.fedecarg.com/category/programming/'>Programming</a>, <a href='http://blog.fedecarg.com/category/python/'>Python</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2190/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2190&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2012/01/22/intercepting-class-method-invocations-using-metaclass-programming-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Check whether your web server is correctly configured</title>
		<link>http://blog.fedecarg.com/2011/12/11/web-server-configuration-security-scanner/</link>
		<comments>http://blog.fedecarg.com/2011/12/11/web-server-configuration-security-scanner/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 13:15:42 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open-source]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2178</guid>
		<description><![CDATA[Last year Zone-H reported a record number of 1.5 million websites defacements. 1 million of those websites where running Apache. When it comes to configuring a web server, some people tend to turn everything on by default. Developers are happy because the functionality that they wanted is available without any extra configuration, and there is [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2178&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Last year <a href="http://twitter.com/#!/fedecarg/statuses/87465788595900416" target="_blank">Zone-H</a> reported a record number of 1.5 million websites defacements. 1 million of those websites where running Apache.</p>
<p>When it comes to configuring a web server, some people tend to turn everything on by default. Developers are happy because the functionality that they wanted is available without any extra configuration, and there is a reduction in support calls due to functionality not working out-of-the-box. This has proven to be a major source of problems for security in general. A web server should start off with total restriction and then access rights should be applied appropriately.</p>
<p>You can check whether your web server is correctly configured by using <a href="http://www.cirt.net/nikto2" target="_blank">Nikto</a>, a great open source vulnerability scanners that is able to scan for quite a large number of web server vulnerabilities. From their site:</p>
<p><em>&#8220;Nikto is an Open Source (GPL) web server scanner which performs comprehensive tests against web servers for multiple items, including over 6400 potentially dangerous files/CGIs, checks for outdated versions of over 1200 servers, and version specific problems on over 270 servers. It also checks for server configuration items such as the presence of multiple index files, HTTP server options, and will attempt to identify installed web servers and software. Scan items and plugins are frequently updated and can be automatically updated.&#8221;</em></p>
<p>I&#8217;m going to run a default scan by just supplying the IP of the target:</p>
<pre>$ cd nikto-2.1.4
$ ./nikto.pl -h 127.0.0.1

- ***** SSL support not available (see docs for SSL install) *****
- Nikto v2.1.4
---------------------------------------------------------------------------
+ Target IP:          127.0.0.1
+ Target Hostname:    localhost.localdomain
+ Target Port:        80
+ Start Time:         2011-12-12 13:06:59
---------------------------------------------------------------------------
+ Server: Apache
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ 6448 items checked: 0 error(s) and 0 item(s) reported on remote host
+ End Time:           2011-12-12 13:08:07 (68 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested</pre>
<p>By looking at the last section of the Nikto report, I can see that there are no issues that need to be addressed.</p>
<p>Tools like <a href="http://www.cirt.net/nikto2" target="_blank">Nikto</a> and <a href="http://code.google.com/p/skipfish/" target="_blank">Skipfish</a> serve as a foundation for professional web application security assessments. Remember, the more tools you use, the better.</p>
<h3>Links</h3>
<ul>
<li><a href="http://www.cirt.net/nikto2" target="_blank">http://www.cirt.net/nikto2</a></li>
<li><a href="http://code.google.com/p/skipfish" target="_blank">http://code.google.com/p/skipfish</a></li>
<li><a href="http://sectools.org" target="_blank">http://sectools.org</a></li>
</ul>
<br />Filed under: <a href='http://blog.fedecarg.com/category/deployment/'>Deployment</a>, <a href='http://blog.fedecarg.com/category/linux/'>Linux</a>, <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>, <a href='http://blog.fedecarg.com/category/security/'>Security</a>, <a href='http://blog.fedecarg.com/category/tools/'>Tools</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2178/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2178&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/12/11/web-server-configuration-security-scanner/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaScript: Retrieve and paginate JSON-encoded data</title>
		<link>http://blog.fedecarg.com/2011/10/09/javascript-retrieve-and-paginate-json-encoded-data/</link>
		<comments>http://blog.fedecarg.com/2011/10/09/javascript-retrieve-and-paginate-json-encoded-data/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 19:43:28 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Open-source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2165</guid>
		<description><![CDATA[I&#8217;ve created a jQuery plugin that allows you to retrieve a large data set in JSON format from a server script and load the data into a list or table with client side pagination enabled. To use this plugin you need to: Include jquery.min.js and jquery.paginate.min.js in your document: &#60;script type="text/javascript" src="js/jquery.min.js"&#62;&#60;/script&#62; &#60;script type="text/javascript" src="js/jquery.paginate.min.js"&#62;&#60;/script&#62; [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2165&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve created a <a href="https://github.com/fedecarg/jquery-paginate" target="_blank">jQuery plugin</a> that allows you to retrieve a large data set in JSON format from a server script and load the data into a list or table with client side pagination enabled. To use this plugin you need to:</p>
<p>Include jquery.min.js and jquery.paginate.min.js in your document:</p>
<pre>&lt;script type="text/javascript" src="js/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="js/jquery.paginate.min.js"&gt;&lt;/script&gt;</pre>
<p>Include a small css to skin the navigation links:</p>
<pre>&lt;style type="text/css"&gt;
a.disabled {
    text-decoration: none;
    color: black;
    cursor: default;
}
&lt;/style&gt;</pre>
<p>Define an ID on the element you want to paginate, for example: &#8220;listitems&#8221;. If you have a more than 10 child elements and you want to avoid displaying them before the javascript is executed, you can set the element as hidden by default:</p>
<pre>&lt;ul id="listitems" style="display:none"&gt;&lt;/ul&gt;</pre>
<p>Place a div in the place you want to display the navigation links:</p>
<pre>&lt;div id="listitems-pagination" style="display:none"&gt;
    &lt;a id="listitems-previous" href="#" class="disabled"&gt;&amp;laquo; Previous&lt;/a&gt;
    &lt;a id="listitems-next" href="#"&gt;Next &amp;raquo;&lt;/a&gt;
&lt;/div&gt;</pre>
<p>Finally, include an initialization script at the bottom of your page like this:</p>
<pre>&lt;script type="text/javascript"&gt;
$(document).ready(function() {
    $.getJSON('data.json', function(data) {
        var items = [];
        $.each(data.items, function(i, item) {
            items.push('&lt;li&gt;' + item + '&lt;/li&gt;');
        });
        $('#listitems').append(items.join(''));
        $('#listitems').paginate({itemsPerPage: 5});
    });
});
&lt;/script&gt;</pre>
<p>You can fork the code on <a href="https://github.com/fedecarg/jquery-paginate" target="_blank">GitHub</a> or <a href="https://github.com/fedecarg/jquery-paginate/zipball/master">download it</a>.</p>
<br />Filed under: <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>, <a href='http://blog.fedecarg.com/category/programming/'>Programming</a>, <a href='http://blog.fedecarg.com/category/web-services/'>Web Services</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2165&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/10/09/javascript-retrieve-and-paginate-json-encoded-data/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Building a RESTful Web API with PHP and Apify</title>
		<link>http://blog.fedecarg.com/2011/09/11/building-a-restful-web-api-with-php-and-apify/</link>
		<comments>http://blog.fedecarg.com/2011/09/11/building-a-restful-web-api-with-php-and-apify/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 20:04:40 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Open-source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2135</guid>
		<description><![CDATA[Apify is a small and powerful open source library that delivers new levels of developer productivity by simplifying the creation of RESTful architectures. You can see it in action here. Web services are a great way to extend your web application, however, adding a web API to an existing web application can be a tedious [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2135&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><img class="size-full wp-image-2145 alignleft" title="apify" src="http://phpimpact.files.wordpress.com/2011/09/logo02.png?w=700" alt=""   /><a href="https://github.com/apify/apify-library">Apify</a> is a small and powerful open source library that delivers new levels of developer productivity by simplifying the creation of RESTful architectures. You can see it in action <a href="http://www.youtube.com/watch?v=7ptoB0yCsDo" target="_blank">here</a>. Web services are a great way to extend your web application, however, adding a web API to an existing web application can be a tedious and time-consuming task. Apify takes certain common patterns found in most web services and abstracts them so that you can quickly write web APIs without having to write too much code.</p>
<p>Apify exposes similar APIs as the Zend Framework, so if you are familiar with the Zend Framework, then you already know how to use Apify. Take a look at the <a href="https://github.com/apify/apify-library/blob/master/app/controllers/UsersController.php" target="_blank">UsersController</a> class.</p>
<h2><strong>Building a RESTful Web API</strong></h2>
<p>In Apify, Controllers handle incoming HTTP requests, interact with the model to get data, and direct domain data to the response object for display. The full request object is injected via the action method and is primarily used to query for request parameters, whether they come from a GET or POST request, or from the URL.</p>
<p>Creating a RESTful Web API with Apify is easy. Each action results in a response, which holds the headers and document to be sent to the user&#8217;s browser. You are responsible for generating the response object inside the action method.</p>
<pre>class UsersController extends Controller
{
    public function indexAction($request)
    {
        // 200 OK
        return new Response();
    }
}</pre>
<p>The response object describes the status code and any headers that are sent. The default response is always 200 OK, however, it is possible to overwrite the default status code and add additional headers:</p>
<pre>class UsersController extends Controller
{
    public function indexAction($request)
    {
        $response = new Response();

        // 401 Unauthorized
        $response-&gt;setCode(Response::UNAUTHORIZED);

        // Cache-Control header
        $response-&gt;setCacheHeader(3600);

        // ETag header
        $response-&gt;setEtagHeader(md5($request-&gt;getUrlPath()));

        // X-RateLimit header
        $limit = 300;
        $remaining = 280;
        $response-&gt;setRateLimitHeader($limit, $remaining);

        // Raw header
        $response-&gt;addHeader('Edge-control: no-store');

        return $response;
    }
}</pre>
<p><strong>Content Negotiation</strong></p>
<p>Apify supports sending responses in HTML, XML, RSS and JSON. In addition, it supports JSONP, which is JSON wrapped in a custom JavaScript function call. There are 3 ways to specify the format you want:</p>
<ul>
<li>Appending a format extension to the end of the URL path (.html, .json, .rss or .xml)</li>
<li>Specifying the response format in the query string. This means a format=xml or format=json parameter for XML or JSON, respectively, which will override the Accept header if there is one.</li>
<li>Sending a standard Accept header in your request (text/html, application/xml or application/json).</li>
</ul>
<p>The acceptContentTypes method indicates that the request only accepts certain content types:</p>
<pre>class UsersController extends Controller
{
    public function indexAction($request)
    {
    	// only accept JSON and XML
        $request-&gt;acceptContentTypes(array('json', 'xml'));

        return new Response();
    }
}</pre>
<p>Apify will render the error message according to the format of the request.</p>
<pre>class UsersController extends Controller
{
    public function indexAction($request)
    {
        $request-&gt;acceptContentTypes(array('json', 'xml'));

    	$response = new Response();
        if (! $request-&gt;hasParam('api_key')) {
            throw new Exception('Missing parameter: api_key', Response::FORBIDDEN);
        }
        $response-&gt;api_key = $request-&gt;getParam('api_key');

        return $response;
    }
}</pre>
<p><strong>Request</strong></p>
<pre>GET /users.json</pre>
<p><strong>Response</strong></p>
<pre>Status: 403 Forbidden
Content-Type: application/json
{
    "code": 403,
    "error": {
        "message": "Missing parameter: api_key",
        "type": "Exception"
    }
}</pre>
<p><strong>Resourceful Routes</strong></p>
<p>Apify supports REST style URL mappings where you can map different HTTP methods, such as GET, POST, PUT and DELETE, to different actions in a controller. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods:</p>
<table width="562">
<tbody>
<tr>
<td><strong>HTTP Method</strong></td>
<td><strong>URL Path</strong></td>
<td><strong>Action</strong></td>
<td><strong>Used for</strong></td>
</tr>
<tr>
<td><span class="caps">GET</span></td>
<td>/users</td>
<td>index</td>
<td>display a list of all users</td>
</tr>
<tr>
<td><span class="caps">GET</span></td>
<td>/users/:id</td>
<td>show</td>
<td>display a specific user</td>
</tr>
<tr>
<td><span class="caps">POST</span></td>
<td>/users</td>
<td>create</td>
<td>create a new user</td>
</tr>
<tr>
<td><span class="caps">PUT</span></td>
<td>/users/:id</td>
<td>update</td>
<td>update a specific user</td>
</tr>
<tr>
<td><span class="caps">DELETE</span></td>
<td>/users/:id</td>
<td>destroy</td>
<td>delete a specific user</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>If you wish to enable RESTful mappings, add the following line to the index.php file:</p>
<pre>try {
    $request = new Request();
    $request-&gt;enableUrlRewriting();
    $request-&gt;enableRestfulMapping();
    $request-&gt;dispatch();
} catch (Exception $e) {
    $request-&gt;catchException($e);
}</pre>
<p>The RESTful UsersController for the above mapping will contain 5 actions as follows:</p>
<pre>class UsersController extends Controller
{
    public function indexAction($request) {}
    public function showAction($request) {}
    public function createAction($request) {}
    public function updateAction($request) {}
    public function destroyAction($request) {}
}</pre>
<p>By convention, each action should map to a particular CRUD operation in the database.</p>
<h2><strong>Building a Web Application</strong></h2>
<p>Building a web application can be as simple as adding a few methods to your controller. The only difference is that each method returns a view object.</p>
<pre>class PostsController extends Controller
{
    /**
     * route: /posts/:id
     *
     * @param $request Request
     * @return View|null
     */
    public function showAction($request)
    {
        $id = $request-&gt;getParam('id');
        $post = $this-&gt;getModel('Post')-&gt;find($id);
        if (! isset($post-&gt;id)) {
            return $request-&gt;redirect('/page-not-found');
        }

        $view = $this-&gt;initView();
        $view-&gt;post = $post;
        $view-&gt;user = $request-&gt;getSession()-&gt;user

        return $view;
    }

    /**
     * route: /posts/create
     *
     * @param $request Request
     * @return View|null
     */
    public function createAction($request)
    {
        $view = $this-&gt;initView();
        if ('POST' !== $request-&gt;getMethod()) {
            return $view;
        }

        try {
            $post = new Post(array(
                'title' =&gt; $request-&gt;getPost('title'),
                'text'  =&gt; $request-&gt;getPost('text')
            ));
        } catch (ValidationException $e) {
            $view-&gt;error = $e-&gt;getMessage();
            return $view;
        }

        $id = $this-&gt;getModel('Post')-&gt;save($post);
        return $request-&gt;redirect('/posts/' . $id);
    }
}</pre>
<p>The validation is performed inside the Post entity class. An exception is thrown if any given value causes the validation to fail. This allows you to easily implement error handling for the code in your controller.</p>
<p><strong>Entity Class</strong></p>
<p>You can add validation to your entity class to ensure that the values sent by the user are correct before saving them to the database:</p>
<pre>class Post extends Entity
{
    protected $id;
    protected $title;
    protected $text;

    // sanitize and validate title (optional)
    public function setTitle($value)
    {
        $value = htmlspecialchars(trim($value), ENT_QUOTES);
        if (empty($value) || strlen($value) &lt; 3) {
            throw new ValidationException('Invalid title');
        }
        $this-&gt;title = $title;
    }

    // sanitize text (optional)
    public function setText($value)
    {
        $this-&gt;text = htmlspecialchars(strip_tags($value), ENT_QUOTES);
    }
}</pre>
<p><strong>Routes</strong></p>
<p>Apify provides a slimmed down version of the Zend Framework router:</p>
<pre>$routes[] = new Route('/posts/:id',
    array(
        'controller' =&gt; 'posts',
        'action'     =&gt; 'show'
    ),
    array(
        'id'         =&gt; '\d+'
    )
);
$routes[] = new Route('/posts/create',
    array(
        'controller' =&gt; 'posts',
        'action'     =&gt; 'create'
    )
);</pre>
<p><strong>HTTP Request</strong></p>
<pre>GET /posts/1</pre>
<p>Incoming requests are dispatched to the controller &#8220;Posts&#8221; and action &#8220;show&#8221;.</p>
<h2><strong>Feedback</strong></h2>
<ul>
<li>If you encounter any problems, please use the <a href="https://github.com/apify/apify-library/issues">issue tracker</a>.</li>
<li>For updates follow <a href="https://twitter.com/fedecarg">@fedecarg</a> on Twitter.</li>
<li>If you like Apify and use it in the wild, let me know.</li>
</ul>
<br />Filed under: <a href='http://blog.fedecarg.com/category/frameworks/'>Frameworks</a>, <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>, <a href='http://blog.fedecarg.com/category/php/'>PHP</a>, <a href='http://blog.fedecarg.com/category/software-architecture/'>Software Architecture</a>, <a href='http://blog.fedecarg.com/category/web-services/'>Web Services</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2135/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2135&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/09/11/building-a-restful-web-api-with-php-and-apify/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>

		<media:content url="http://phpimpact.files.wordpress.com/2011/09/logo02.png" medium="image">
			<media:title type="html">apify</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaScript: Asynchronous Script Loading and Lazy Loading</title>
		<link>http://blog.fedecarg.com/2011/07/12/javascript-asynchronous-script-loading-and-lazy-loading/</link>
		<comments>http://blog.fedecarg.com/2011/07/12/javascript-asynchronous-script-loading-and-lazy-loading/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 21:04:54 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Architecture]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2118</guid>
		<description><![CDATA[Most of the time remote scripts are included at the end of an HTML document, right before the closing body tag. This is because browsers are single threaded and when they encounter a script tag, they halt any other processes until they download and parse the script. By including scripts at the end, you allow [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2118&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Most of the time remote scripts are included at the end of an HTML document, right before the closing body tag. This is because browsers are single threaded and when they encounter a script tag, they halt any other processes until they download and parse the script. By including scripts at the end, you allow the browser to download and render all page elements, style sheets and images without any unnecessary delay. Also, if the browser renders the page before executing any script, you know that all page elements are already available to retrieve.</p>
<p>However, websites like Facebook for example, use a more advanced technique. They include scripts dynamically via DOM methods. This technique, which I&#8217;ll briefly explain here, is known as &#8220;Asynchronous Script Loading&#8221;.</p>
<p>Lets take a look at the script that Facebook uses to download its JS library:</p>
<pre>(function () {
    var e = document.createElement('script');
    e.src = 'http://connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
}());</pre>
<p>When you dynamically append a script to a page, the browser does not halt other processes, so it continues rendering page elements and downloading resources. The best place to put this code is right after the opening body tag. This allows Facebook initialization to happen in parallel with the initialization on the rest of the page.</p>
<p>Facebook also makes non-blocking loading of the script easy to use by providing the fbAsyncInit hook. If this global function is defined, it will be executed when the library is loaded.</p>
<pre>window.fbAsyncInit = function () {
    FB.init({
        appId: 'YOUR APP ID',
        status: true,
        cookie: true,
        xfbml: true
    });
};</pre>
<p>Once the library has loaded, Facebook checks the value of window.fbAsyncInit.hasRun and if it&#8217;s false it makes a call to the fbAsyncInit function:</p>
<pre>if (window.fbAsyncInit &amp;&amp; !window.fbAsyncInit.hasRun) {
    window.fbAsyncInit.hasRun = true;
    fbAsyncInit();
}</pre>
<p>Now, what if you want to load multiple files asynchronously, or you need to include a small amount of code at page load and then download other scripts only when needed? Loading scripts on demand is called &#8220;Lazy Loading&#8221;. There are many libraries that exist specifically for this purpose, however, you only need a few lines of JavaScript to do this.</p>
<p>Here is an example:</p>
<pre>$L = function (c, d) {
    for (var b = c.length, e = b, f = function () {
            if (!(this.readyState
            		&amp;&amp; this.readyState !== "complete"
            		&amp;&amp; this.readyState !== "loaded")) {
                this.onload = this.onreadystatechange = null;
                --e || d()
            }
        }, g = document.getElementsByTagName("head")[0], i = function (h) {
            var a = document.createElement("script");
            a.async = true;
            a.src = h;
            a.onload = a.onreadystatechange = f;
            g.appendChild(a)
        }; b;) i(c[--b])
};</pre>
<p>The best place to put this code is inside the head tag. You can then use the $L function to asynchronously load your scripts on demand. $L takes two arguments: an array (c) and a callback function (d).</p>
<pre>var scripts = [];
scripts[0] = 'http://www.google-analytics.com/ga.js';
scripts[1] = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js';

$L(scripts, function () {
    console.log("ga and jquery scripts loaded");
});

$L(['http://connect.facebook.net/en_US/all.js'], function () {
    console.log("facebook script loaded");
    window.fbAsyncInit.hasRun = true;
    FB.init({
        appId: 'YOUR APP ID',
        status: true,
        cookie: true,
        xfbml: true
    });
});</pre>
<p>You can see this script in action <a href="http://fbrell.com/auth/account-info" target="_blank">here</a> (right click -&gt; view page source).</p>
<br />Filed under: <a href='http://blog.fedecarg.com/category/design-patterns/'>Design Patterns</a>, <a href='http://blog.fedecarg.com/category/programming/'>Programming</a>, <a href='http://blog.fedecarg.com/category/software-architecture/'>Software Architecture</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2118&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/07/12/javascript-asynchronous-script-loading-and-lazy-loading/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Collective Wisdom from the Experts</title>
		<link>http://blog.fedecarg.com/2011/06/06/collective-wisdom-from-the-experts/</link>
		<comments>http://blog.fedecarg.com/2011/06/06/collective-wisdom-from-the-experts/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 23:06:53 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Software Architecture]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2109</guid>
		<description><![CDATA[I&#8217;ve finally had a chance to read a book I bought a while ago called &#8220;97 Things Every Software Architect Should Know &#8211; Collective Wisdom from the Experts&#8220;. Not the shortest title for a book, but very descriptive. I bought this book at the OSCON Conference in Portland last year. It&#8217;s an interesting book and [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2109&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve finally had a chance to read a book I bought a while ago called &#8220;<a href="http://www.amazon.co.uk/Things-Every-Software-Architect-Should/dp/059652269X">97 Things Every Software Architect Should Know &#8211; Collective Wisdom from the Experts</a>&#8220;. Not the shortest title for a book, but very descriptive. I bought this book at the OSCON Conference in Portland last year. It&#8217;s an interesting book and I&#8217;m sure anyone involved in software development would benefit from reading it.</p>
<p>More than 40 architects, including <a href="http://www.nealford.com/">Neal Ford</a> and <a href="http://www.michaelnygard.com/">Michael Nygard</a>, offer advice for communicating with stakeholders, eliminating complexity, empowering developers, and many more practical lessons they&#8217;ve learned from years of experience. The book offers valuable information on key development issues that go way beyond technology. Most of the advice given is from personal experience and is good for any project leader involved with software development no matter their job title. However, you have to keep in mind that this is a compilation book, so don&#8217;t expect in-depth information or theoritical knowledge about architecture design and software engineering.</p>
<p>Here are some extracts from the book:</p>
<p><strong>Simplify essential complexity; diminish accidental complexity</strong> &#8211; By Neal Ford</p>
<p>Frameworks that solve specific problems are useful. Over-engineered frameworks add more complexity than they relieve. It&#8217;s the duty of the architect to solve the problems inherent in essential complexity without introducing accidental complexity.</p>
<p><strong>Chances are your biggest problem isn&#8217;t technical</strong> &#8211; By Mark Ramm</p>
<p>Most projects are built by people, and those people are the foundation for success and failure. So, it pays to think about what it takes to help make those people successful.</p>
<p><strong>Communication is King</strong> &#8211; By Mark Richards</p>
<p>Every software architect should know how to communicate the goals and objectives of a software project. The key to effective communication is clarity and leadership.</p>
<p>Keeping developers in the dark about the big picture or why decisions were made is a clear recipe for disaster. Having the developer on your side creates a collaborative environment whereby decisions you make as an architect are validated. In turn, you get buy-in from developers by keeping them involved in the architecture process</p>
<p><strong>Architecting is about balancing</strong> &#8211; By Randy Stafford</p>
<p>When we think of architecting software, we tend to think first of classical technical activities, like modularizing systems, defining interfaces, allocating responsibility, applying patterns, and optimizing performance.  Architects also need to consider security, usability, supportability, release management, and deployment options, among others things.  But these technical and procedural issues must be balanced with the needs of stakeholders and their interests.</p>
<p>Software architecting is about more than just the classical technical activities; it is about balancing technical requirements with the business requirements of stakeholders in the project.</p>
<p><strong>Skyscrapers aren&#8217;t scalable</strong> &#8211; By Michael Nygard</p>
<p>We cannot easily add lanes to roads, but we&#8217;ve learned how to easily add features to software. This isn&#8217;t a defect of our software processes, but a virtue of the medium in which we work. It&#8217;s OK to release an application that only does a few things, as long as users value those things enough to pay for them.</p>
<p><strong>Quantify</strong> &#8211; Keith Braithwaite</p>
<p>The next time someone tells you that a system needs to be &#8220;scalable&#8221; ask them where new users are going to come from and why. Ask how many and by when? Reject &#8220;Lots&#8221; and &#8220;soon&#8221; as answers. Uncertain quantitative criteria must be given as a range: the least, the nominal, and the most. If this range cannot be given, then the required behavior is not understood.</p>
<p>Some simple questions to ask: How many? In what period? How often? How soon? Increasing or decreasing? At what rate? If these questions cannot be answered then the need is not understood. The answers should be in the business case for the system and if they are not, then some hard thinking needs to be done.</p>
<p><strong>Architects must be hands on</strong> &#8211; By John Davies</p>
<p>A good architect should lead by example, he/she should be able to fulfill any of the positions within his team from wiring the network, and configuring the build process to writing the unit tests and running benchmarks. It is perfectly acceptable for team members to have more in-depth knowledge in their specific areas but it&#8217;s difficult to imagine how team members can have confidence in their architect if the architect doesn&#8217;t understand the technology.</p>
<p><strong>Use uncertainty as a driver</strong> &#8211; By Kevlin Henney</p>
<p>Confronted with two options, most people think that the most important thing to do is to make a choice between them. In design (software or otherwise), it is not. The presence of two options is an indicator that you need to consider uncertainty in the design. Use the uncertainty as a driver to determine where you can defer commitment to details and where you can partition and abstract to reduce the significance of design decisions.</p>
<p>You can purchase &#8220;<a href="http://www.amazon.co.uk/Things-Every-Software-Architect-Should/dp/059652269X">97 Things Every Software Architect Should Know</a>&#8221; from Amazon.</p>
<br />Filed under: <a href='http://blog.fedecarg.com/category/software-architecture/'>Software Architecture</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2109&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/06/06/collective-wisdom-from-the-experts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>NoSQL solutions: Membase, Redis, CouchDB and MongoDB</title>
		<link>http://blog.fedecarg.com/2011/01/25/nosql-solutions-membase-redis-couchdb-and-mongodb/</link>
		<comments>http://blog.fedecarg.com/2011/01/25/nosql-solutions-membase-redis-couchdb-and-mongodb/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 12:47:17 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Open-source]]></category>
		<category><![CDATA[Software Architecture]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2048</guid>
		<description><![CDATA[Each database has specific use cases and every solution has a sweet spot in terms of data, hardware, setup and operation. Here are some of the most popular key-value and document data stores: Key-value Membase Developed by members of the memcached core team. Simple (key value store), fast (low, predictable latency) and elastic (effortlessly grow [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2048&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Each database has specific use cases and every solution has a sweet spot in terms of data, hardware, setup and operation. Here are some of the most popular key-value and document data stores:</p>
<h3>Key-value</h3>
<p><a href="http://membase.org/">Membase</a></p>
<ul>
<li>Developed by members of the memcached core team.</li>
<li>Simple (key value store), fast (low, predictable latency) and elastic (effortlessly grow or shrink a cluster).</li>
<li>Extensions are possible through a plug-in architecture (full-text search, backup, etc).</li>
<li>Supports Memcached ASCII and Binary protocols (uses existent Memcached libraries and clients).</li>
<li>Guarantees data consistency.</li>
<li>High-speed failover (server failures recoverable in under 100ms).</li>
<li>User management, alerts and logging and audit trail.</li>
</ul>
<p><a href="http://code.google.com/p/redis/" target="_blank">Redis</a></p>
<ul>
<li>Developed by Salvatore Sanfilippo and acquired by VMWare in 2010.</li>
<li><a href="http://code.google.com/p/redis/wiki/Benchmarks">Very fast</a>. Non-blocking I/O. Single threaded.</li>
<li>Data is held in memory but can be persisted by written to disk asynchronously.</li>
<li>Values can be strings, lists or sets.</li>
<li>Built-in support for master/slave replication.</li>
<li>Distributes the dataset across multiple Redis instances.</li>
</ul>
<h3>Document-oriented</h3>
<p>The major benefit of using a document database comes from the fact that  while it has all the benefits of a key/value store, you aren&#8217;t limited  to just querying by key. However, documented-oriented databases and  MapReduce aren&#8217;t appropriate for every situation.</p>
<p><a href="http://couchdb.apache.org/">CouchDB</a></p>
<ul>
<li>High read performance.</li>
<li>Supports bulk inserts.</li>
<li>Good for consistent master-master replica databases that are geographically distributed and often offline.</li>
<li>Good for intense versioning.</li>
<li>Android, MeeGo and WebOS include services for syncing locally stored data with a CouchDB non-relational database in the cloud.</li>
<li>Better than MongoDB at durability.</li>
<li>Uses REST as its interface to the database. It doesn&#8217;t have &#8220;queries&#8221; but instead uses &#8220;views&#8221;.</li>
<li> Makes heavy use of the file system cache (so more RAM is always better).</li>
<li>The database must be compacted periodically.</li>
<li>Conflicts on transactions must be handled by the programmer manually (e.g. if someone else has updated the document since it was fetched, then CouchDB relies on the application to resolve versioning issues).</li>
<li>Scales through asynchronous replication but lacks an auto-sharding mechanism. Reads are distributed to any server while writes must be propagated to all servers.</li>
</ul>
<p><a href="http://www.mongodb.org/" target="_blank">MongoDB</a></p>
<ul>
<li>High write performance. Good for systems with very high update rates.</li>
<li>It has the flexibility to replace a relational database in a wider range of scenarios.</li>
<li>Supports auto-sharding.</li>
<li>More oriented towards master/slave replication.</li>
<li>Compaction of the database is not necessary.</li>
<li>Both CouchDB and MongoDB support map/reduce operations.</li>
<li>Supports dynamic ad hoc queries via a JSON-style query language.</li>
<li>The pre-filtering provided by the query attribute doesn&#8217;t have a direct counterpart in CouchDB. It also allows post-filtering of aggregated values.</li>
<li>Relies on language-specific database drivers for access to the database.</li>
</ul>
<h3>Links</h3>
<ul>
<li><a href="http://horicky.blogspot.com/2009/11/nosql-patterns.html">NoSQL Patterns</a> by Ricky Ho</li>
<li><a href="http://try.redis-db.com/" target="_blank">Redis interactive tutorial</a></li>
<li><a href="http://simonwillison.net/static/2010/redis-tutorial/" target="_blank">Redis tutorial</a> by Simon Willison (NoSQL Europe Conference)</li>
<li><a href="http://try.mongodb.org/">MongoDB interactive tutorial</a></li>
</ul>
<br />Filed under: <a href='http://blog.fedecarg.com/category/databases/'>Databases</a>, <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>, <a href='http://blog.fedecarg.com/category/software-architecture/'>Software Architecture</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2048/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2048/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2048&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2011/01/25/nosql-solutions-membase-redis-couchdb-and-mongodb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>OSCON 2010, The O&#8217;Reilly Open Source Convention</title>
		<link>http://blog.fedecarg.com/2010/08/09/oscon-2010-the-oreilly-open-source-convention/</link>
		<comments>http://blog.fedecarg.com/2010/08/09/oscon-2010-the-oreilly-open-source-convention/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 10:10:02 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Open-source]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=2029</guid>
		<description><![CDATA[A couple of weeks ago I attended the O’Reilly Open Source Convention (OSCON) in Portland. OSCON has hundreds of sessions and activities focused on all aspects of open source software. I met some great people, the talks were good and I saw some promising ideas and technologies. Workshops attended Android for Java Developers Marko Gargenta [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2029&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A couple of weeks ago I attended the O’Reilly Open Source Convention (OSCON) in  Portland. OSCON has hundreds of sessions and activities focused on all  aspects of open source software. I met some great people, the talks were  good and I saw some promising ideas and technologies.</p>
<p><strong>Workshops attended</strong></p>
<ul>
<li>Android for Java Developers<br />
<span style="color:#888888;"><em>Marko Gargenta (Marakana)</em></span></li>
<li>Building a NoSQL Data Cloud<br />
<span style="color:#888888;"><em>Krishna Sankar (Cisco Systems Inc)</em></span></li>
<li>Building Native Mobile Apps Using Open Source<br />
<span style="color:#888888;">Kevin Whinnery (Appcelerator)</span></li>
</ul>
<p><strong>Sessions attended</strong></p>
<ul>
<li>Building Mobile Apps with HTML, CSS, and JavaScript<br />
<span style="color:#888888;"><em>Jonathan Stark (Jonathan Stark Consulting)</em></span></li>
<li>Open Source Tool Chains for Cloud Computing<br />
<span style="color:#888888;"><em>Mark Hinkle (Zenoss), John Willis (Opscode, Inc.), Alex Honor</em></span></li>
<li>Doctor, I Have a Problem with My Innovation.<br />
<span style="color:#888888;"><em>Rolf Skyberg (eBay, Inc.)</em></span></li>
<li>Ingex: Bringing Open Source to the Broadcast Industry<br />
<span style="color:#888888;"><em>By Brendan Quinn (BBC R&amp;D)</em></span></li>
<li>membase.org: The Simple, Fast, Elastic NoSQL Database<br />
<span style="color:#888888;"><em>Matt Ingenthron (NorthScale, Inc.)</em></span></li>
<li>Introducing WebM: High Quality, Royalty-Free, Open Source Video<br />
<span style="color:#888888;"><em>John Koleszar (Google, Inc.)</em></span></li>
<li>Whiskey, Tango, Foxtrot: Understanding API Activity<br />
<span style="color:#888888;"><em>Clay Loveless (Mashery)</em></span></li>
<li>Deploying an Open Source Private Cloud On a Shoe String Budget<br />
<span style="color:#888888;"><em>Louis Danuser (AT&amp;T Labs, Inc.)</em></span></li>
<li>Eucalyptus: The Open Source Infrastructure for Cloud Computing<br />
<span style="color:#888888;"><em>Shashi Mysore (Eucalyptus Systems Inc.)</em></span></li>
<li>Hadoop, Pig, and Twitter<br />
<span style="color:#888888;"><em>Kevin Weil (Twitter, Inc.)</em></span></li>
<li>Mahout: Mammoth Scale Machine Learning<br />
<span style="color:#888888;"><em>Robin Anil (Apache Software Foundation)</em></span></li>
<li>BlackBerry development for Web Application Developers<br />
<span style="color:#888888;"><em>Kevin Falcone (Best Practical Solutions)</em></span></li>
<li>Practical Concurrency<br />
<span style="color:#888888;"><em>Tim Bray (Google, Inc.)</em></span></li>
<li>Scribe &#8211; Moving Data at Massive Scale<br />
<span style="color:#888888;"><em>Robert Johnson (Facebook)</em></span></li>
<li>Make Open Easy<br />
<span style="color:#888888;"><em>Dan Bentley (Google)</em></span></li>
</ul>
<br />Filed under: <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/2029/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/2029/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=2029&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2010/08/09/oscon-2010-the-oreilly-open-source-convention/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Most Visited Posts of 2009</title>
		<link>http://blog.fedecarg.com/2010/04/02/most-visited-posts-of-2009/</link>
		<comments>http://blog.fedecarg.com/2010/04/02/most-visited-posts-of-2009/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 20:50:10 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=1999</guid>
		<description><![CDATA[Here are the most visited posts of 2009 according to unique page views: MySQL Split String Function Domain-Driven Design: Sample Application updated Domain-Driven Design and MVC Architectures Domain-Driven Design: The Repository updated Domain-Driven Design: Data Access Strategies Building a Web Service Client using the Zend Framework Geo Proximity Search: The Haversine Equation Running Quercus in [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=1999&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Here are the most visited posts of 2009 according to unique page views:</p>
<ul>
<li><a href="http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/" target="_blank">MySQL Split String Function</a></li>
<li><a href="http://blog.fedecarg.com/2009/03/22/domain-driven-design-sample-application/" target="_blank">Domain-Driven Design: Sample Application</a> <em><strong>updated</strong></em></li>
<li><a href="http://blog.fedecarg.com/2009/03/11/domain-driven-design-and-mvc-architectures/" target="_blank">Domain-Driven Design and MVC Architectures</a></li>
<li><a href="http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/" target="_blank">Domain-Driven Design: The Repository</a> <em><strong>updated</strong></em></li>
<li><a href="http://blog.fedecarg.com/2009/03/12/domain-driven-design-and-data-access-strategies/" target="_blank">Domain-Driven Design: Data Access Strategies</a></li>
<li><a href="http://blog.fedecarg.com/2009/02/15/building-a-web-service-client-using-the-zend-framework/" target="_blank">Building a Web Service Client using the Zend Framework</a></li>
<li><a href="http://blog.fedecarg.com/2009/02/08/geo-proximity-search-the-haversine-equation/" target="_blank">Geo Proximity Search: The Haversine Equation</a></li>
<li><a href="http://blog.fedecarg.com/2009/01/04/running-quercus-in-jetty-web-server/">Running Quercus in Jetty Web Server</a></li>
<li><a href="http://blog.fedecarg.com/2009/05/13/is-this-the-best-open-source-cms-ever-created/" target="_blank">Is this the best open source CMS ever created?</a></li>
<li><a href="http://blog.fedecarg.com/2009/09/19/zend-framework-dal-daos-and-datamappers/" target="_blank">Zend Framework DAL: DAOs and DataMappers</a> <em><strong>updated</strong></em></li>
<li><a href="http://blog.fedecarg.com/2009/06/16/java-c-python-and-nested-loops/" target="_blank">Java, C, Python and nested loops</a></li>
<li><a href="http://blog.fedecarg.com/2009/11/01/testing-zend-framework-action-controllers-with-mocks/">Testing Zend Framework Action Controllers With Mocks</a> <em><strong>updated</strong></em></li>
<li><a href="http://blog.fedecarg.com/2009/10/02/database-replication-adapter-for-zend-framework-applications/" target="_blank">Database Replication Adapter</a> <em><strong>updated</strong></em></li>
<li><a href="http://blog.fedecarg.com/2009/07/06/increase-speed-and-reduce-bandwidth-usage/" target="_blank">Increase speed and reduce bandwidth usage</a></li>
<li><a href="http://blog.fedecarg.com/2009/02/01/zend-framework-automatic-dependency-tracking/" target="_blank">Zend Framework Automatic Dependency Tracking</a></li>
</ul>
<br />Filed under: <a href='http://blog.fedecarg.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/1999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/1999/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=1999&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2010/04/02/most-visited-posts-of-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Implementing Dynamic Finders and Parsing Method Expressions</title>
		<link>http://blog.fedecarg.com/2010/03/22/implementing-dynamic-finders-and-parsing-method-expressions/</link>
		<comments>http://blog.fedecarg.com/2010/03/22/implementing-dynamic-finders-and-parsing-method-expressions/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 23:51:51 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Open-source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software Architecture]]></category>

		<guid isPermaLink="false">http://blog.fedecarg.com/?p=1903</guid>
		<description><![CDATA[Most ORMs support the concept of dynamic finders. A dynamic finder looks like a normal method invocation, but the method itself doesn&#8217;t exist, instead, it&#8217;s generated dynamically and processed via another method at runtime. A good example of this is Ruby. When you invoke a method that doesn&#8217;t exist, it raises a NoMethodError exception, unless [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=1903&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Most ORMs support the concept of dynamic finders. A dynamic finder looks like a normal method invocation, but the method itself doesn&#8217;t exist, instead, it&#8217;s generated dynamically and processed via another method at runtime.</p>
<p>A good example of this is Ruby. When you invoke a method that doesn&#8217;t exist, it raises a NoMethodError exception, unless you define &#8220;method_missing&#8221;. Rails <a href="http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-2/activerecord/lib/active_record/base.rb" target="_blank">ActiveRecord::Base</a> class implements some of its magic thanks to this method. For example, find_by_title(title) and find_by_title_and_date(title, date) are turned into:</p>
<pre>find(:first, :conditions =&gt; ["title = ?", title])
find(:first, :conditions =&gt; ["title = ? AND date = ?", title, date])</pre>
<p>What&#8217;s nice about Ruby is that the language allows you to <a href="http://blog.jayfields.com/2008/02/ruby-dynamically-define-method.html" target="_blank">define methods dynamically</a> using the &#8220;define_method&#8221; method. That&#8217;s how Rails defines each dynamic finder in the class after it is first invoked, so that future attempts to use it do not run through the &#8220;method_missing&#8221; method.</p>
<h3><strong>Method Expressions</strong></h3>
<p>GORM, Grails ORM library, introduces the concept of dynamic method expressions. A method expression is made up of the prefix such as &#8220;findBy&#8221; followed by an expression that combines one or more properties. Grails takes advantage of Groovy features to provide dynamic methods:</p>
<pre>findByTitle("Example")
findByTitleLike("Exa%")</pre>
<p>Method expressions can also use a boolean operator to combine two criteria:</p>
<pre>findAllByTitleLikeAndDateGreaterThan("Exampl%", '2010-03-23')</pre>
<p>In this case we are using AND in the middle of the query to make sure both conditions are satisfied, but you could equally use OR:</p>
<pre>findAllByTitleLikeOrDateGreaterThan("Exampl%", '2010-03-23')</pre>
<h3><strong>Parsing Method Expressions</strong></h3>
<p><a href="http://fedecarg.com/wiki/expressionparser/Home" target="_blank">MethodExpressionParser</a> is a PHP library for parsing method expressions. It&#8217;s designed to quickly and easily parse method expressions and construct conditions based on attribute names and arguments.</p>
<p><strong>Description</strong></p>
<pre>[finderMethod]([attribute][expression][logicalOperator])?[attribute][expression]</pre>
<p><strong>Expressions</strong></p>
<ul>
<li>LessThan: Less than the given value</li>
<li>LessThanEquals: Less than or equal a give value</li>
<li>GreaterThan: Greater than a given value</li>
<li>GreaterThanEquals: Greater than or equal a given value</li>
<li>Like: Equivalent to a SQL like expression</li>
<li>NotEqual: Negates equality</li>
<li>IsNotNull: Not a null value (doesn&#8217;t require an argument)</li>
<li>IsNull: Is a null value (doesn&#8217;t require an argument)</li>
</ul>
<p><strong>Examples</strong></p>
<pre>findByTitleAndDate('Example', date('Y-m-d'));
SELECT * FROM book WHERE title = ? AND date = ?

findByTitleOrDate('Example', date('Y-m-d'))
SELECT * FROM book WHERE title = ? OR date = ?

findByPublisherOrTitleAndDate('Name', 'Example', date('Y-m-d'))
SELECT * FROM book WHERE publisher = ? OR (title = ? AND date = ?)

findByPublisherInAndTitle(array('Name1', 'Name2'), 'Example')
SELECT * FROM book WHERE publisher IN (?, ?) AND date = ?

findByTitleLikeAndDateNotNull('Examp%')
SELECT * FROM book WHERE title LIKE ? AND date NOT NULL

findByIdOrTitleAndDateNotNull(1, 'Example')
SELECT * FROM book WHERE (id = ?) OR (title = ? AND date NOT NULL)</pre>
<p><strong>Example 1:</strong></p>
<pre>findByTitleLikeAndDateNotNull('Examp%');</pre>
<p>Outputs:</p>
<pre>array
  0 =&gt;
    array
      0 =&gt;
        array
          'attribute' =&gt; string 'title'
          'expression' =&gt; string 'Like'
          'format' =&gt; string '%s LIKE ?'
          'placeholders' =&gt; int 1
          'argument' =&gt; string 'Examp%'
      1 =&gt;
        array
          'attribute' =&gt; string 'date'
          'expression' =&gt; string 'NotNull'
          'format' =&gt; string '%s IS NOT NULL'
          'placeholders' =&gt; int 0
          'argument' =&gt; null</pre>
<p><strong>Example 2:</strong></p>
<pre>findByTitleAndPublisherNameOrTitleAndPublisherName('Title', 'a', 'Title', 'b');</pre>
<p>Outputs:</p>
<pre>array
  0 =&gt;
    array
      0 =&gt;
        array
          'attribute' =&gt; string 'title'
          'expression' =&gt; string 'Equals'
          'format' =&gt; string '%s = ?'
          'placeholders' =&gt; int 1
          'argument' =&gt; string 'Title'
      1 =&gt;
        array
          'attribute' =&gt; string 'publisher_name'
          'expression' =&gt; string 'Equals'
          'format' =&gt; string '%s = ?'
          'placeholders' =&gt; int 1
          'argument' =&gt; string 'a'
  1 =&gt;
    array
      0 =&gt;
        array
          'attribute' =&gt; string 'title'
          'expression' =&gt; string 'Equals'
          'format' =&gt; string '%s = ?'
          'placeholders' =&gt; int 1
          'argument' =&gt; string 'Title'
      1 =&gt;
        array
          'attribute' =&gt; string 'publisher_name'
          'expression' =&gt; string 'Equals'
          'format' =&gt; string '%s = ?'
          'placeholders' =&gt; int 1
          'argument' =&gt; string 'b'</pre>
<p>See more examples: <a href="http://fedecarg.com/wiki/expressionparser/Home" target="_blank">Project Wiki</a></p>
<h3><strong>Usage</strong></h3>
<pre>class EntityRepository
{
    private $methodExpressionParser;

    // Return a single instance of MethodExpressionParser
    public function getMethodExpressionParser() {
    }

    // Finder methods
    public function findBy($conditions) {
        var_dump($conditions);
    }
    public function findAllBy($conditions) {
        var_dump($conditions);
    }

    // Invoke finder methods
    public function __call($method, $args) {
        if ('f' === $method{0}) {
            try {
                $result = $this-&gt;getMethodExpressionParser()-&gt;parse($method, $args);
                $finderMethod = key($result);
                $conditions = $result[$finderMethod];
            } catch (MethodExpressionParserException $e) {
                $message = sprintf('%s: %s()', $e-&gt;getMessage(), $method);
                throw new EntityRepositoryException($message);
            }
            return $this-&gt;$finderMethod($conditions);
        }

        $message = 'Invalid method call: ' . __METHOD__;
        throw new BadMethodCallException($message);
    }
}</pre>
<h3><strong>Performance</strong></h3>
<p>PHP doesn&#8217;t allow you to define methods dynamically, this means that every time you invoke a finder method the parser has to search, extract and map all the attribute names and expressions. To avoid introducing this performance overhead you can cache the attribute names. For example:</p>
<pre>class EntityRepository
{
    private $methodExpressionParser;
    private $classMetadata;

    // Return a single instance of MethodExpressionParser
    public function getMethodExpressionParser() {
    }

    // Return a single instance of ClassMetadata
    public function getClassMetadata() {
    }

    // Invoke finder methods
    public function __call($method, $args) {
        if ('f' === $method{0}) {
            $parser = $this-&gt;getMethodExpressionParser();
            $classMetadata = $this-&gt;getClassMetadata();
            try {
                $finderMethod = $parser-&gt;determineFinderMethod($method);
                if ($classMetadata-&gt;hasMissingMethod($method)) {
                    $attributes = $classMetadata-&gt;getMethodAttributes($method);
                    $conditions = $parser-&gt;map($args, $attributes);
                } else {
                    $expressions = substr($method, strlen($finderMethod));
                    $attributes = $this-&gt;extractAttributeNames($expressions);
                    $conditions = $parser-&gt;map($args, $attributes);
                    $classMetadata-&gt;setMethodAttributes($method, $attributes);
                }
            } catch (MethodExpressionParserException $e) {
                $message = sprintf('%s: %s()', $e-&gt;getMessage(), $method);
                throw new EntityRepositoryException($message);
            }
            return $this-&gt;$finderMethod($conditions);
        }

        $message = 'Invalid method call: ' . __METHOD__;
        throw new BadMethodCallException($message);
    }
}</pre>
<p>The Expression objects are lazy-loaded, depending on the expressions found in the method name.</p>
<h3><strong>Extensibility</strong></h3>
<p>The MethodExpressionParser class was designed with extensibility in mind, allowing you to add new Expressions to the library.</p>
<pre>abstract class Expression {
}
class EqualsExpression extends Expression {
}</pre>
<h3><strong>Source Code</strong></h3>
<p>Browse source code: <a href="http://fedecarg.com/repositories/show/expressionparser" target="_blank"></p>
<p>http://fedecarg.com/repositories/show/expressionparser</a></p>
<p>Check out the current development trunk with:</p>
<pre>$ svn checkout http://svn.fedecarg.com/repo/Zf/Orm</pre>
<br />Filed under: <a href='http://blog.fedecarg.com/category/databases/'>Databases</a>, <a href='http://blog.fedecarg.com/category/frameworks/'>Frameworks</a>, <a href='http://blog.fedecarg.com/category/open-source/'>Open-source</a>, <a href='http://blog.fedecarg.com/category/php/'>PHP</a>, <a href='http://blog.fedecarg.com/category/programming/'>Programming</a>, <a href='http://blog.fedecarg.com/category/software-architecture/'>Software Architecture</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/phpimpact.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/phpimpact.wordpress.com/1903/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fedecarg.com&#038;blog=920807&#038;post=1903&#038;subd=phpimpact&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fedecarg.com/2010/03/22/implementing-dynamic-finders-and-parsing-method-expressions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/b8d6b74fce406b08bb28806ce7377e61?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">phpimpact</media:title>
		</media:content>
	</item>
	</channel>
</rss>
