David A. Windham thumbnail

Laravel

I like to dabble with new development frameworks for fun. I’ll just check out whatever is the trending and run through a basic setup. Projects like https://github.com/gothinkster/realworld are like a toy for me. I’ve worked with a limited group of frameworks more extensively because I’ve built or worked on projects with theses: Drupal, Django, Rails. Sinatra, Meteor, and Express. I know I’m a bit late on Laravel, but it’s still new to me. I think I started seeing some We Work Remotely gigs rolling through my reader and those sent me down the Laravel1 rabbit hole.

Something about Laravel gelled with me. I wasn’t exactly sure at first… in fact, I was a bit skeptical ( I think I’m getting that way in my old age ) and I didn’t think that a PHP project could grab my attention. I mean I figured I’d be digging into Elixer and Pheonix and I was recently digging on GoLang and Revel. Although most of what I do is simple content and file management running on WordPress. It’s seems like for most of the other projects it’s the exact the same stuff different framework…  authentication, permissions, routing, some models, and nowadays.. maybe consuming or producing an API. I don’t think it was just me falling back on old trusty PHP. I thought maybe I just like Laracast2 like I liked Railscasts. One afternoon after a session of Laracasts, I decided that I’d figure out who the host is since I’d been watching and listening to his instruction.  I found an interview3 with him about how he started with Laravel and he mentioned the comments. That’s it. That’s what gelled with me. It’s the comments… and the formatting, spacing and overall attention to detail in the structure. Here is the Routing/RouteAction.php file.

namespace Illuminate\Routing;

use LogicException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use UnexpectedValueException;

class RouteAction
{
    /**
     * Parse the given action into an array.
     *
     * @param  string  $uri
     * @param  mixed  $action
     * @return array
     */
    public static function parse($uri, $action)
    {
        // If no action is passed in right away, we assume the user will make use of
        // fluent routing. In that case, we set a default closure, to be executed
        // if the user never explicitly sets an action to handle the given uri.
        if (is_null($action)) {
            return static::missingAction($uri);
        }

        // If the action is already a Closure instance, we will just set that instance
        // as the "uses" property, because there is nothing else we need to do when
        // it is available. Otherwise we will need to find it in the action list.
        if (is_callable($action)) {
            return ! is_array($action) ? ['uses' => $action] : [
                'uses' => $action[0].'@'.$action[1],
                'controller' => $action[0].'@'.$action[1],
            ];
        }

        // If no "uses" property has been set, we will dig through the array to find a
        // Closure instance within this list. We will set the first Closure we come
        // across into the "uses" property that will get fired off by this route.
        elseif (! isset($action['uses'])) {
            $action['uses'] = static::findCallable($action);
        }

        if (is_string($action['uses']) && ! Str::contains($action['uses'], '@')) {
            $action['uses'] = static::makeInvokable($action['uses']);
        }

        return $action;
    }

    /**
     * Get an action for a route that has no action.
     *
     * @param  string  $uri
     * @return array
     */
    protected static function missingAction($uri)
    {
        return ['uses' => function () use ($uri) {
            throw new LogicException("Route for [{$uri}] has no action.");
        }];
    }

    /**
     * Find the callable in an action array.
     *
     * @param  array  $action
     * @return callable
     */
    protected static function findCallable(array $action)
    {
        return Arr::first($action, function ($value, $key) {
            return is_callable($value) && is_numeric($key);
        });
    }

    /**
     * Make an action for an invokable controller.
     *
     * @param  string $action
     * @return string
     *
     * @throws \UnexpectedValueException
     */
    protected static function makeInvokable($action)
    {
        if (! method_exists($action, '__invoke')) {
            throw new UnexpectedValueException("Invalid route action: [{$action}].");
        }

        return $action.'@__invoke';
    }
}

Simple as that. No benchmarks, no language preference, no new-fangled features. It’s just the aesthetics of the code. I think that’s part of the reason why everyone fell on Rails too. I’m the same way. If I’m really into something, I’ll take care to make sure that I’m systematically tabbing, formatting, and commenting the code. Yes, I know… it’s easy to run some post processing for any sort of formatting preferences, but I like to do it manually. And it’s that the sorta detail in Laravel that grabbed my attention. I try not to force a project onto a framework and I generally try pick the best framework for each project. Most of the time, it’s generally the framework that makes it the quickest and easiest.  Although I’m a bit late on this one, I’m sure I’ll do a follow up on Laravel when I’ve got a decent project under my belt. In the meantime, I’ll be looking to make someone’s project fit into Laravel relatively soon. 



1. Laravel – https://en.wikipedia.org/wiki/Laravel
2. Laracasts – https://laracasts.com/
2. Jeffrey Way – PHP Sydney – https://www.youtube.com/watch?v=kHoVE0kCnZg